/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // ---------------------------------------------- // Name: XSCX121SetupCycle // Description: provides implementation of X121 // Setup on Specified Market Cycle ... // // // 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.xea.class.mq5" #include "../Classes/x-saherelm.x121.setup.cycle.class.mq5" // // Definitions ... // // Model all Trades Data as this Structure ... struct XTradeInfo { // int pushers; // Signal Pushers datetime time; // Issue Time (Open Position) string symbol; // Trading Symbol double entry; // Entry Price double volume; // Volume string provider; // Signaller ENUM_TIMEFRAMES period; // Trading Timeframe ENUM_X_POSITION_TYPES type; // Position Type // ulong ticket; // Position Ticket double profit; // Profit on Close double commission; // Commission double swap; // Swap string message; // Close Reason datetime endTime; // End Time // int bullishSigns; // Bullish Signs On Signal Time int bearishSigns; // Bearish Signs On Signal Time // double bullishScore; // Bullish Score On Signal Time double bearishScore; // Bearish Score On Signal Time // double volumeOSC; // Volume Weight On Signal Time // X121SetupConditions cConditions; // Generated Current Conditions X121SetupConditions sConditions; // Generated Short Conditions X121SetupConditions mConditions; // Generated Medium Conditions X121SetupConditions lConditions; // Generated Long Conditions X121SetupConditions hConditions; // Generated Hind Conditions // // Constructor ... void XTradeInfo() { Clean(); } // // Tools ... // // Cleanup ... void Clean() { // time = NULL; type = NULL; symbol = NULL; period = NULL; endTime = NULL; message = NULL; provider = NULL; // swap = 0; entry = 0; ticket = 0; profit = 0; volume = 0; pushers = 0; volumeOSC = 0; commission = 0; bullishSigns = 0; bearishSigns = 0; bullishScore = 0; bearishScore = 0; // cConditions.Clean(); sConditions.Clean(); mConditions.Clean(); lConditions.Clean(); hConditions.Clean(); // ResetGrid(); ResetSupport(); ResetRecovery(); } // bool Fill( const XSignal &_signal, int _pushers, double _volumeOSC, int _bullishSigns, int _bearishSigns, double _bullishScore, double _bearishScore, X121SetupConditions &_cConditions, X121SetupConditions &_sConditions, X121SetupConditions &_mConditions, X121SetupConditions &_lConditions, X121SetupConditions &_hConditions // ) { // bool result = false; // result = // IsValid(_signal.symbol) && IsValid(_signal.period) && IsValid(_signal.provider) // ; // if (!result) { return result; } // pushers = _pushers; time = _signal.time; entry = _signal.entry; symbol = _signal.symbol; period = _signal.period; volume = _signal.volume; provider = _signal.provider; type = ToPositionType(_signal.type); // cConditions = _cConditions; sConditions = _sConditions; mConditions = _mConditions; lConditions = _lConditions; hConditions = _hConditions; // volumeOSC = _volumeOSC; // bullishSigns = _bullishSigns; bearishSigns = _bearishSigns; // bullishScore = _bullishScore; bearishScore = _bearishScore; // X121SignalGenerator generator; XSignal tSignal = _signal; generator.GenerateSupportPivots( tSignal, pivots // ); tSignal.Clean(); int pivotsCount = ArraySize(pivots); if (!IsValidSize(pivotsCount)) { // Print("Dangerous Position ..."); } // return result; } // bool IsOwn( ulong _ticket // ) { // bool result = false; // result = _ticket == ticket; // return result; } // bool IsOwn( string _symbol, string _provider, ENUM_TIMEFRAMES _period // ) { // bool result = false; // result = // IsValid(_symbol) && IsValid(_provider) && IsValid(_period) && // symbol == _symbol && provider == _provider && period == _period // ; // return result; } // // Data Collector ... // bool IsValid() { // bool result = false; // result = // ticket > 0 && IsValid(time) && IsValid(symbol) && IsValid(period) // ; // return result; } // int GetAge() { // int result = -1; // if (!IsValid(symbol) || !IsValid(time) || !IsValid(endTime) || !IsValid(period)) { return result; } // int startIndex = iBarShift( symbol, period, time, false // ); // int endIndex = iBarShift( symbol, period, endTime, false // ); // result = MathAbs(startIndex - endIndex); // return result; } // string GetFileName() { // string result = NULL; // if (!IsValid()) { return result; } // result = // symbol + "\\" + ToString(type) + "\\" + (profit >= 0 ? "Profit" : "Loss") + "\\" + provider + "_" + ToString(ticket) + "_" + ToString(period) + "_" + ToFormatString(time) // ; // return result; } // string ToString() { // string result = NULL; // string cConditionsStr = cConditions .GenerateSummary( false, // Only Commons ... true, // Only Conditions ... false, // Include Score ... false // Include False Conditions ... ); string sConditionsStr = sConditions .GenerateSummary( false, // Only Commons ... true, // Only Conditions ... false, // Include Score ... false // Include False Conditions ... ); string mConditionsStr = mConditions .GenerateSummary( false, // Only Commons ... true, // Only Conditions ... false, // Include Score ... false // Include False Conditions ... ); string lConditionsStr = lConditions .GenerateSummary( false, // Only Commons ... true, // Only Conditions ... false, // Include Score ... false // Include False Conditions ... ); string hConditionsStr = hConditions .GenerateSummary( false, // Only Commons ... true, // Only Conditions ... false, // Include Score ... false // Include False Conditions ... ); // int age = GetAge(); // result = // ToString("Ticket", ticket) + ToString("Symbol", symbol) + ToString("Period", period) + ToString("Entry", entry) + ToString("Provider", provider) + ToString("Type", ToString(type)) + ToString("Time", time) + ToString("Pushers", pushers) + "-------------" + "\n" + ToString("VolumeOSC", volumeOSC) + ToString("BullishSigns", bullishSigns) + ToString("BearishSigns", bearishSigns) + ToString("BullishScore", bullishScore) + ToString("BearishScore", bearishScore) + "-------------" + "\n" + ToString("Volume", volume) + ToString("Profit", profit) + ToString("Commission", commission) + ToString("Swap", swap) + ToString("End Time", endTime) + ToString("Age", age) + ToString("Message", message) + "-------------" + "\n" + "Conditions" + "\n" + "-------------" + "\n" + "-------------" + "\n" + "CURRENT [" + ToString(cConditions.period) + "]" + "\n" + "-------------" + "\n" + cConditionsStr + "\n" + "-------------" + "\n" + "SHORT [" + ToString(sConditions.period) + "]" + "\n" + "-------------" + "\n" + sConditionsStr + "\n" + "-------------" + "\n" + "MEDIUM [" + ToString(mConditions.period) + "]" + "\n" + "-------------" + "\n" + mConditionsStr + "\n" + "-------------" + "\n" + "LONG [" + ToString(lConditions.period) + "]" + "\n" + "-------------" + "\n" + lConditionsStr + "\n" + "-------------" + "\n" + "HIND [" + ToString(hConditions.period) + "]" + "\n" + "-------------" + "\n" + hConditionsStr + "\n" + // "" // ; // return result; } // // These are Some Helpers for Trading Controls and do not relate to Main // purpose of Trade Handler ... // // Supporting ... // double pivots[]; // void ResetSupport() { Clean(pivots); } // // Retrieve Support Signal ... bool HasSupport( XSignal &support // ) { // bool result = false; // result = IsValid(); if (!result) { return result; } // int pivotsCount = ArraySize(pivots); result = IsValidSize(pivotsCount); if (!result) { return result; } // support.Clean(); // ENUM_POSITION_TYPE sType = type == X_POSITION_TYPE_LONG ? POSITION_TYPE_BUY : POSITION_TYPE_SELL; // bool isLong = IsLong(type); // ENUM_POSITION_TYPE cType = GetOpposit(sType); double cEntry = GetEntry( symbol, cType // ); // double pivot = 0; int pivotIndex = -1; for (int i = 0; i < pivotsCount; i++) { // double iPivot = pivots[i]; if (iPivot <= 0) { continue; } // result = isLong ? cEntry < entry && cEntry <= iPivot : cEntry > entry && cEntry >= iPivot; if (result) { // pivot = iPivot; pivotIndex = i; break; } } // if (result) { // result = support.Prepare( symbol, XEQMSupportToken + XINDirectionalToken, period, cType, X_ORDER_MODE_MARKET, cEntry, volume * 2, 0, 0 // ); if (result) { // string comment = GenerateSupportTag(ticket); support.comment = comment; // // Prepare Directional Support ... XSignal mSup; result = mSup.Prepare( symbol, XEQMSupportToken + XDirectionalToken, period, sType, X_ORDER_MODE_STOP, entry, volume, 0, 0 // ); if (result) { // string comment = GenerateSupportTag(ticket); mSup.comment = comment; // AddRef( mSup, support.supports // ); // result = ArrayRemove( pivots, pivotIndex, 1 // ); } } } // if (!result) { support.Clean(); } // return result; } // bool RemovePivot( double pivot, int index // ) { // bool result = false; // result = IsValid() && IsValidIndex(index) && ArraySize(pivots) > index; if (!result) { return result; } // result = ArrayRemove( pivots, index, 1 // ); // return result; } // // Grid System Calculations ... // int gLevel; // Number of Grids double gEntry; // Represents Next Grid Signal's Entry double gVolume; // Represent Next Grid Signal's Volume // void ResetGrid() { // gEntry = 0; gLevel = 0; gVolume = 0; } // void SetGrid( double nextEntry, double nextVolume // ) { // gEntry = nextEntry; gVolume = nextVolume; } // // Prepare Data For Next Grid ... void PrepareNextGrid( double distance, double volumeMultiplier // ) { // bool isValid = // IsValid() && entry > 0 && volume > 0 && distance > 0 && volumeMultiplier > 0 // ; bool isLong = IsLong(type); // double distancePrice = PointToPrice( distance, symbol // ); // double selectedEntry = gEntry <= 0 ? entry : gEntry; double selectedVolume = gVolume <= 0 ? volume : gVolume; // double nextEntry = isLong ? selectedEntry - distancePrice : selectedEntry + distancePrice; double nextVolume = selectedVolume * volumeMultiplier; // SetGrid( nextEntry, nextVolume // ); } // // Check if a Grid Signal Exists Prepared and // Provide it ... bool HasGrid( XSignal &signal, // Result Signal double distance, double volumeMultiplier // ) { // bool result = false; // signal.Clean(); // result = IsValid() && distance > 0 && volumeMultiplier > 0; if (!result) { return result; } // bool isLong = IsLong(type); // ENUM_POSITION_TYPE gType = isLong ? POSITION_TYPE_BUY : POSITION_TYPE_SELL; // double cEntry = GetEntry( symbol, gType // ); // result = isLong ? cEntry <= gEntry : cEntry >= gEntry; if (!result) { return result; } // result = signal.Prepare( symbol, provider, period, gType, X_ORDER_MODE_MARKET, cEntry, gVolume, 0, // SL ... 0 // TP ... ); // if (result) { // // set Support Token ... string comment = GenerateSupportTag(ticket); signal.comment = comment; // PrepareNextGrid( distance, volumeMultiplier // ); // gLevel++; } // return result; } // // Recovery Zone System ... // ENUM_POSITION_TYPE rLastRecoveryType; // Last Executed Recovery Signal's Type double rLongEntry; // Represent Next Recovery Long Signal's Entry double rShortEntry; // Represent Next Recovery Short Signal's Entry double rVolume; // Represent Next Recovery Signal's Volume double rZoneUpper; // Zone Recovery Upper Bound double rZoneLower; // Zone Recovery Lower Bound int rLevel; // Number of Recoveries // void ResetRecovery() { // rLevel = 0; rVolume = 0; rLongEntry = 0; rZoneUpper = 0; rZoneLower = 0; rShortEntry = 0; } // void SetRecovery( double nextLongEntry, double nextShortEntry, double zoneUpper, double zoneLower, double nextVolume // ) { // rVolume = nextVolume; rZoneUpper = zoneUpper; rZoneLower = zoneLower; rLongEntry = nextLongEntry; rShortEntry = nextShortEntry; } // void PrepareNextRecovery( double distance, // Define Target Based On Zones double volumeMultiplier, // Volume Multiplier ENUM_POSITION_TYPE lastType // Last Type ) { // bool isValid = // IsValid() && entry > 0 && volume > 0 && distance > 0 && volumeMultiplier > 0 // ; // bool isLong = IsLong(lastType); // double distancePrice = PointToPrice( distance, symbol // ); // double selectedEntry = isLong ? rLongEntry <= 0 ? entry : rLongEntry : rShortEntry <= 0 ? entry : rShortEntry; double selectedVolume = rVolume <= 0 ? volume : rVolume; // double nextLongEntry = isLong ? selectedEntry : selectedEntry + distancePrice; double nextShortEntry = isLong ? selectedEntry - distancePrice : selectedEntry; // double nextVolume = selectedVolume * volumeMultiplier; // rLevel % 2 == 1 // ? volume // : volume * volumeMultiplier; // double zoneUpper = rZoneUpper > 0 ? rZoneUpper : isLong ? entry + distancePrice : entry + (distancePrice * 2); double zoneLower = rZoneLower > 0 ? rZoneLower : isLong ? entry + (distancePrice * 2) : entry - distancePrice; // SetRecovery( nextLongEntry, nextShortEntry, zoneUpper, zoneLower, nextVolume // ); // rLastRecoveryType = lastType; } // // Check if a Recovery Signal Exists Prepared and // Provide it ... bool HasRecovery( XSignal &signal, // Result Signal ... double distance, double volumeMultiplier // ) { // bool result = false; // signal.Clean(); // result = // IsValid() && entry > 0 && volume > 0 && distance > 0 && volumeMultiplier > 0 // ; if (!result) { return result; } // double distancePrice = PointToPrice( distance, symbol // ); // bool isLong = IsLong(type); bool isLastLong = IsLong(rLastRecoveryType); // // Check For Long Recovery ... double cLongEntry = GetEntry( symbol, POSITION_TYPE_BUY // ); bool hasLongRecovery = !isLastLong && rLongEntry > 0 && cLongEntry >= rLongEntry; // // Check For Short Recovery ... double cShortEntry = GetEntry( symbol, POSITION_TYPE_SELL // ); bool hasShortRecovery = isLastLong && rShortEntry > 0 && cShortEntry <= rShortEntry; // result = hasLongRecovery || hasShortRecovery; if (!result) { return result; } // ENUM_POSITION_TYPE rType = hasLongRecovery ? POSITION_TYPE_BUY : POSITION_TYPE_SELL; // double rEntry = hasLongRecovery ? cLongEntry : cShortEntry; // double rTP = hasLongRecovery ? rZoneUpper : rZoneLower; // double rSL = hasLongRecovery ? rZoneLower : rZoneUpper; // result = signal.Prepare( symbol, provider, period, rType, X_ORDER_MODE_MARKET, rEntry, rVolume, 0, // rSL, // SL ... 0 // rTP // TP ... ); if (result) { // // set Support Token ... string comment = GenerateSupportTag(ticket); signal.comment = comment; // rLevel++; // PrepareNextRecovery( distance, volumeMultiplier, rType // ); } // return result; } }; // // a Class For Read and Write Trade Info Data in Files ... class XTradeInfoCollector { // // Public ... public: // // Props ... // // Constructor(s) ... void XTradeInfoCollector( string _path = NULL // Base Path ) { // mAccount = new XSCAccount(); // if (IsValid(_path)) { mPath = _path; } else { mPath = "XTradeInfo" + "\\" + mAccount.GetCompany(); } } // // Deconstructor ... void ~XTradeInfoCollector() {} // bool IsExists(XTradeInfo &item) { // bool result = false; // int mHandler = GetFileHandlerForRead(item); result = mHandler != INVALID_HANDLE; FileClose(mHandler); // return result; } // bool Save(XTradeInfo &item) { // bool result = false; // // Check info is Valid ... result = item.IsValid(); if (!result) { return result; } // string content = item.ToString(); result = IsValid(content); if (!result) { return result; } // int mHandler = GetFileHandlerForWrite(item); result = mHandler != INVALID_HANDLE; if (!result) { return result; } // FileWrite(mHandler, content); FileFlush(mHandler); FileClose(mHandler); // return result; } // // Protected ... protected: // // Private ... private: // // Props ... // string mPath; // Base Path ... // XSCAccount *mAccount; // string GetFilePath(XTradeInfo &item) { // string fileName = item.GetFileName(); // return GetFilePath(fileName); } string GetFilePath(string fileName) { // string result = ""; // result = // mPath + "\\" + fileName + ".x121.log" // ; // return result; } // int GetFileHandlerForRead(XTradeInfo &item) { // int result = INVALID_HANDLE; // string filePath = GetFilePath(item); if (!IsValid(filePath)) { return result; } // result = FileOpen( filePath, FILE_READ | FILE_TXT // ); // return result; } int GetFileHandlerForWrite(XTradeInfo &item) { // int result = INVALID_HANDLE; // string filePath = GetFilePath(item); if (!IsValid(filePath)) { return result; } // result = FileOpen( filePath, FILE_READ | FILE_WRITE | FILE_TXT // ); // return result; } }; // // a Class for Holding all required data for Specified Trade // such as: // - Signal; // - Position; // - Conditions; // - Scores; // - etc ... class XTradeHandler { // public: // // Props ... // // Constructor ... void XTradeHandler( XSCTrade *trade // an Instance of Trader Class ) { // Clean(data); SetSave(false); mTrader = trade; collector = new XTradeInfoCollector(); } // // Getter(s) / Setter(s) ... // // Others ... // bool GetSave() { return mSave; } // void SetSave(bool value) { mSave = value; } // // Trailling Stop ... // bool AllowTrailStop() { return mAllowTrailStop; } // void AllowTrailStop(bool value) { mAllowTrailStop = value; } // double NextTrailPoint() { return mNextTrailPoint; } // void NextTrailPoint(double value) { // if (value < 0) { value = 0; } // mNextTrailPoint = value; } // double FirstTrailPoint() { return mFirstTrailPoint; } // void FirstTrailPoint(double value) { // if (value < 0) { value = 0; } // mFirstTrailPoint = value; } // double NextTrailDistance() { return mNextTrailDistance; } // void NextTrailDistance(double value) { // if (value < 0) { value = 0; } // mNextTrailDistance = value; } // double FirstTrailDistance() { return mFirstTrailDistance; } // void FirstTrailDistance(double value) { // if (value < 0) { value = 0; } // mFirstTrailDistance = value; } // bool EnableTrailling() { // bool result = false; // result = // AllowTrailStop() && NextTrailPoint() > 0 && FirstTrailPoint() > 0 && NextTrailDistance() > 0 && FirstTrailDistance() > 0 // ; // return result; } // // Supporting ... // bool AllowSupport() { return mAllowSupport; } // void AllowSupport(bool value) { mAllowSupport = value; } // double SupportDistance() { return mSupportDistance; } // void SupportDistance(double value) { // if (value < 0) { value = 0; } // mSupportDistance = value; } // int MaxNumberOfSupports() { return mMaxNumberOfSupports; } // void MaxNumberOfSupports(int value) { // if (value < 0) { value = 0; } // mMaxNumberOfSupports = value; } // double SupportVolumeMultiplier() { return mSupportVolumeMultiplier; } // void SupportVolumeMultiplier(double value) { // if (value < 1) { value = 1; } // mSupportVolumeMultiplier = value; } // double MaxAllowedSupportVolume() { return mMaxAllowedSupportVolume; } // void MaxAllowedSupportVolume(double value) { // if (value < 0.01) { value = 0.01; } // mMaxAllowedSupportVolume = value; } // bool EnableSupport() { // bool result = false; // result = // AllowSupport() && SupportDistance() > 0 && MaxNumberOfSupports() >= 0 && SupportVolumeMultiplier() > 0 // ; // return result; } // // Grid ... // bool AllowGrid() { return mAllowGrid; } // void AllowGrid(bool value) { mAllowGrid = value; } // int MaxNumberOfGrids() { return mMaxNumberOfGrids; } // void MaxNumberOfGrids(int value) { // if (value < 0) { value = 0; } // mMaxNumberOfGrids = value; } // double GridDistance() { return mGridDistance; } // void GridDistance(double value) { // if (value < 0) { value = 0; } // mGridDistance = value; } // double GridVolumeMultiplier() { return mGridVolumeMultiplier; } // void GridVolumeMultiplier(double value) { // if (value < 1) { value = 1; } // mGridVolumeMultiplier = value; } // double MaxAllowedGridVolume() { return mMaxAllowedGridVolume; } // void MaxAllowedGridVolume(double value) { // if (value < 0.01) { value = 0.01; } // mMaxAllowedGridVolume = value; } // // Check Grid Properties to Validate it's Enable or not ... bool EnableGrid() { // bool result = false; // result = // AllowGrid() && GridDistance() > 0 && MaxNumberOfGrids() >= 0 && GridVolumeMultiplier() > 0 // ; // return result; } // // Recovery System ... // bool AllowRecovery() { return mAllowRecovery; } // void AllowRecovery(bool value) { mAllowRecovery = value; } // int MaxNumberOfRecoveries() { return mMaxNumberOfRecoveries; } // void MaxNumberOfRecoveries(int value) { // if (value < 0) { value = 0; } // mMaxNumberOfRecoveries = value; } // double RecoveryDistance() { return mRecoveryDistance; } // void RecoveryDistance(double value) { // if (value < 0) { value = 0; } // mRecoveryDistance = value; } // double RecoveryVolumeMultiplier() { return mRecoveryVolumeMultiplier; } // void RecoveryVolumeMultiplier(double value) { // if (value < 1) { value = 1; } // mRecoveryVolumeMultiplier = value; } // double MaxAllowedRecoveryVolume() { return mMaxAllowedRecoveryVolume; } // void MaxAllowedRecoveryVolume(double value) { // if (value < 0.01) { value = 0.01; } // mMaxAllowedRecoveryVolume = value; } // // Check Recovery Properties to Validate it's Enable or not ... bool EnableRecovery() { // bool result = false; // result = // AllowRecovery() && RecoveryDistance() > 0 && MaxNumberOfRecoveries() >= 0 && RecoveryVolumeMultiplier() > 0 // ; // return result; } // // Tools ... // int Count() { return ArraySize(data); } // int FindIndex(ulong ticket) { // int result = -1; // int count = Count(); if (!IsValidSize(count)) { return result; } // for (int i = 0; i < count; i++) { // XTradeInfo iInfo = data[i]; // bool isOwn = iInfo.IsOwn( ticket // ); if (isOwn) { // result = i; break; } } // return result; } // int FindIndex(XSignal &signal) { // int result = -1; // int count = Count(); if (!IsValidSize(count)) { return result; } // for (int i = 0; i < count; i++) { // XTradeInfo iInfo = data[i]; // bool isOWN = // iInfo.time == signal.time && iInfo.symbol == signal.symbol && iInfo.volume == signal.volume && iInfo.period == signal.period && iInfo.provider == signal.provider && iInfo.type == ToPositionType(signal.type) // ; // if (isOWN) { // result = i; break; } } // return result; } // void Add( XSignal &signal, int pushers, double volumeOSC, int bullishSigns, int bearishSigns, double bullishScore, double bearishScore, X121SetupConditions &cConditions, X121SetupConditions &sConditions, X121SetupConditions &mConditions, X121SetupConditions &lConditions, X121SetupConditions &hConditions // ) { // XTradeInfo signalInfo; bool isFilled = signalInfo.Fill( signal, pushers, volumeOSC, bullishSigns, bearishSigns, bullishScore, bearishScore, cConditions, sConditions, mConditions, lConditions, hConditions // ); if (!isFilled) { return; } // AddRef( signalInfo, data // ); } // void Remove(XSignal &signal) { // int infoIDX = FindIndex(signal); if (!IsValidIndex(infoIDX)) { return; } // ArrayRemove( data, infoIDX, 1 // ); } // void Update(XSignal &signal) { // if (!signal.IsValid() || !signal.IsExecuted()) { return; } // int infoIDX = FindIndex(signal); if (!IsValidIndex(infoIDX)) { return; } // data[infoIDX].ticket = signal.positionId; // // Find Orders for Accessing Commission ... XDeal deals[]; int dealsCount = mTrader.GetDeals( deals, signal.symbol, signal.provider, signal.period, NULL, DEAL_ENTRY_IN // Position Open Deal ... ); if (!IsValidSize(dealsCount)) { return; } // for (int i = 0; i < dealsCount; i++) { // XDeal iDeal = deals[i]; // if (iDeal.positionId == signal.positionId) { data[infoIDX].commission = iDeal.commission; } } // // Check if Grid System Enable or Not ... if (EnableGrid()) { // // Here we Prepare Handler Structure for // Next Grid Position ... data[infoIDX].PrepareNextGrid( GridDistance(), GridVolumeMultiplier() // ); } // // Check if Recovery System Enable or Not ... if (EnableRecovery()) { // data[infoIDX].PrepareNextRecovery( GridDistance(), GridVolumeMultiplier(), signal.type // ); } } // void Update(XDeal &deal) { // if (!deal.IsValid()) { return; } // int infoIDX = FindIndex(deal.positionId); if (!IsValidIndex(infoIDX)) { return; } // data[infoIDX].swap = deal.swap; data[infoIDX].endTime = deal.time; data[infoIDX].profit = deal.profit; // string message = deal.reason == DEAL_REASON_TP ? "TP" : "SL"; data[infoIDX].message = message; // Finish(infoIDX); } // void Update(XPosition &position) { // if (!position.IsValid()) { return; } // int infoIDX = FindIndex(position.ticket); if (!IsValidIndex(infoIDX)) { return; } // data[infoIDX].swap = position.swap; data[infoIDX].endTime = TimeCurrent(); data[infoIDX].profit = position.profit; data[infoIDX].message = position.comment; // Finish(infoIDX); } // // Sync ... void Sync() { // int count = Count(); if (!IsValidSize(count)) { return; } // int mustRemoved[]; for (int i = 0; i < count; i++) { // XTradeInfo iInfo = data[i]; // if (iInfo.ticket > 0 && !mTrader.IsOpen(iInfo.ticket)) { // AddSpecific( i, mustRemoved // ); } } // int mustRemovedCount = ArraySize(mustRemoved); if (!IsValidSize(mustRemovedCount)) { return; } // for (int i = 0; i < mustRemovedCount; i++) { // ArrayRemove( data, i, 1 // ); } } // // Protection Handlers ... // // Handle Do All Protecting ... int DoProtect( XSignal &signals[], // if PRotecting Generate Some Support Signals, Holds them here XSCX121SetupCycles *&setups[], // Number of Setups bool forceState = false // ) { // int result = 0; // // Calling Protection Algorithms ... // // Trailling ... if (EnableTrailling()) { int traillings = HandleTrailling(); } // if (AllowSupport()) { // XSignal supports[]; int supportsCount = RequestForSupport( supports, setups // ); // if (IsValidSize(supportsCount)) { // Copy( supports, signals, false // ); } } // // Grid ... if (EnableGrid()) { // XSignal grids[]; int gridsCount = RequestForGrid(grids); if (IsValidSize(gridsCount)) { // Copy( grids, signals, false // ); } } // // Recovery ... if (EnableRecovery()) { // XSignal recoveries[]; int recoveriesCount = RequestForRecovery(recoveries); if (IsValidSize(recoveriesCount)) { // Copy( recoveries, signals, false // ); } } // result = ArraySize(signals); // return result; } // // Protected ... protected: // // Props ... XSCTrade *mTrader; XTradeInfo data[]; XTradeInfoCollector *collector; // bool mSave; // Save Results ... // // Trailling ... bool mAllowTrailStop; // Enable Trailling Stop Losses double mNextTrailPoint; // Next Trailling Step double mFirstTrailPoint; // First Stop Trail double mFirstTrailDistance; // Start Trailling Distance double mNextTrailDistance; // Next Trailling Distance // // Supporting ... bool mAllowSupport; // Allow Support Signals double mSupportDistance; // Supporting Distance int mMaxNumberOfSupports; // Max Number of Support Signals double mSupportVolumeMultiplier; // Support Signals Volume Multiplier double mMaxAllowedSupportVolume; // Max Allowed Support Signals Volume // // Grid ... bool mAllowGrid; // Allow Grid Signals int mMaxNumberOfGrids; // Max Number of Grid Signals double mGridDistance; // Grid Distance double mGridVolumeMultiplier; // Grid Volume Multiplier double mMaxAllowedGridVolume; // Max Allowed Grid Signals Volume // // Recovery ... bool mAllowRecovery; // Allow Recovery Signals int mMaxNumberOfRecoveries; // Max Number of Recovery Signals double mRecoveryDistance; // Recovery Distance double mRecoveryVolumeMultiplier; // Recovery Volume Multiplier double mMaxAllowedRecoveryVolume; // Max Allowed Recovery Signals Volume // // Tools ... // void Finish(int index) { // XTradeInfo info = data[index]; if (!info.IsValid()) { return; } // ArrayRemove( data, index, 1 // ); // if (GetSave()) { collector.Save(info); } } // // Protection Methods ... // int HandleTrailling() { // int result = 0; // // Check Trailling is Enabled or not ... if (!EnableTrailling()) { return result; } // // Do Synch Before Start Trailing ... Sync(); // // Since Trailing Done based On In Profit Positions ... // First we Check if ... XPosition positions[]; int positionsCount = mTrader.GetInProfitPositions(positions); if (!IsValidSize(positionsCount)) { return result; } // for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; // // ignore Support Positions ... bool isSupport = IsSupport(iPosition.comment); if (isSupport) { continue; } // // Only Trail Positions which they Hasnt any Support ... bool hasSupport = mTrader.HasSupport(iPosition.ticket); result = !hasSupport; if (!result) { return result; } // // Find Positin Info Index ... int idx = FindIndex(iPosition.ticket); if (!IsValidIndex(idx)) { continue; } // bool isLong = IsLong(iPosition.type); // // Here we Select Price for SL Trailling ... double usedPrice = 0; if (iPosition.sl != 0) { // if (isLong) { // if (iPosition.sl < iPosition.entry) { usedPrice = iPosition.entry; } else { usedPrice = iPosition.sl; } } else { // if (iPosition.sl > iPosition.entry) { usedPrice = iPosition.entry; } else { usedPrice = iPosition.sl; } } } else { usedPrice = iPosition.entry; } // double nextTrailPoint = NextTrailPoint(); double firstTrailPoint = FirstTrailPoint(); double nextTrailDistance = NextTrailDistance(); double firstTrailDistance = FirstTrailDistance(); // bool isFirstTrail = usedPrice == iPosition.entry; // double usedTrailDiff = isFirstTrail ? MathMax(firstTrailPoint, firstTrailDistance) : MathMax(nextTrailPoint, nextTrailDistance); // double iExit = GetExit( iPosition.symbol, iPosition.type // ); double iPriceDistance = MathAbs(usedPrice - iExit); double iPriceDistanceInPoint = PriceToPoint( iPriceDistance, iPosition.symbol // ); // bool canTrail = iPriceDistanceInPoint >= usedTrailDiff; if (!canTrail) { continue; } // usedTrailDiff = isFirstTrail ? MathMin(firstTrailPoint, firstTrailDistance) : MathMin(nextTrailPoint, nextTrailDistance); double usedTrailDiffPrice = PointToPrice( usedTrailDiff, iPosition.symbol // ); // double sl = isLong ? usedPrice + usedTrailDiffPrice : usedPrice - usedTrailDiffPrice; string comment = PrepareSLTrailTag(iPosition.comment); // bool isModified = mTrader.Modify( iPosition.ticket, sl, iPosition.tp, comment // ); if (isModified) { result++; } } // return result; } // int RequestForSupport( XSignal &signals[], XSCX121SetupCycles *&setups[] // ) { // int result = 0; // Clean(signals); // if (!AllowSupport()) { return result; } // Sync(); // int count = Count(); if (!IsValidSize(count)) { return result; } // for (int i = 0; i < count; i++) { // XSignal iSupport; double iPivot = -1; int iPivotIDX = -1; bool hasSupport = data[i].HasSupport( iSupport // ); if (hasSupport) { // AddRef( iSupport, signals // ); } } // result = ArraySize(signals); // // TODO: Complete this Later ... return result; // // Validate Setups Count ... // int setupsCount = ArraySize(setups); // if (!IsValidSize(setupsCount)) // { // return result; // } // // // // Implement Supporting Mechanism ... // // // // Extracting In Drawdown Positions ... // XPosition positions[]; // int positionsCount = mTrader.GetInDrawdownPositions( // positions // // ); // if (!IsValidSize(positionsCount)) // { // return result; // } // // // double supportDistance = SupportDistance(); // int maxNUmberOfSupports = MaxNumberOfSupports(); // double maxAllowedVolume = MaxAllowedSupportVolume(); // double volumeMultiplier = SupportVolumeMultiplier(); // // // X121SignalGenerator signalGenerator; // // // for (int i = 0; i < positionsCount; i++) // { // // // XPosition iPosition = positions[i]; // // // // Check Position is not Support Position ... // bool isSupport = IsSupport(iPosition.comment); // if (isSupport) // { // continue; // } // // // // Find Related Setp ... // int idx = FindSetupIndex( // iPosition.symbol, // setups // // ); // if (!IsValidIndex(idx)) // { // continue; // } // // // int index = FindIndex(iPosition.ticket); // if (!IsValidIndex(index)) // { // continue; // } // // // // Check Position must atleast 20 Point in drawdown ... // // // double onePointPrice = PointToPrice( // 1, // iPosition.symbol // // ); // // // double iExitPrice = GetExit( // iPosition.symbol, // iPosition.type // // ); // // // double priceDiff = MathAbs(iPosition.entry - iExitPrice); // double priceDiffPoints = priceDiff / onePointPrice; // // // bool isFarEnough = priceDiffPoints >= (supportDistance / 2); // if (!isFarEnough) // { // continue; // } // // // // Check Support COunts and etc ... // // implementing supporting mechanis ... // // // } // // // result = ArraySize(signals); // return result; } // int RequestForGrid(XSignal &signals[]) { // int result = 0; // Clean(signals); // if (!EnableGrid()) { return result; } // int maxAllowed = MaxNumberOfGrids(); double maxAllowedVolume = MaxAllowedGridVolume(); // int count = Count(); if (!IsValidSize(count)) { return result; } // for (int i = 0; i < count; i++) { // // Check Count ... bool isMaxPassed = maxAllowed <= 0 ? true : data[i].gLevel < maxAllowed; if (!isMaxPassed) { continue; } // XSignal iSignal; bool hasGrid = data[i].HasGrid( iSignal, GridDistance(), GridVolumeMultiplier() // ); // if (hasGrid) { // // Check Max Volume ... iSignal.volume = maxAllowedVolume <= 0 ? iSignal.volume : MathMin(iSignal.volume, maxAllowedVolume); // AddRef( iSignal, signals // ); } } // result = ArraySize(signals); // return result; } // int RequestForRecovery(XSignal &signals[]) { // int result = 0; // Clean(signals); // if (!EnableRecovery()) { return result; } // int maxAllowed = MaxNumberOfRecoveries(); double maxAllowedVolume = MaxAllowedRecoveryVolume(); // int count = Count(); if (!IsValidSize(count)) { return result; } // for (int i = 0; i < count; i++) { // // Check Count ... bool isMaxPassed = maxAllowed <= 0 ? true : data[i].rLevel < maxAllowed; if (!isMaxPassed) { continue; } // XSignal iSignal; bool hasRecovery = data[i].HasRecovery( iSignal, RecoveryDistance(), RecoveryVolumeMultiplier() // ); // if (hasRecovery) { // // Check Max Volume ... iSignal.volume = maxAllowedVolume <= 0 ? iSignal.volume : MathMin(iSignal.volume, maxAllowedVolume); // AddRef( iSignal, signals // ); } } // result = ArraySize(signals); // return result; } // int FindSetupIndex( string symbol, XSCX121SetupCycles *&setups[] // ) { // int result = 0; // if (!IsValid(symbol)) { return result; } // for (int i = 0; i < ArraySize(setups); i++) { // if (setups[i].GetSymbol() == symbol) { // result = i; break; } } // return result; } // void AddHotLevelsToZones( XSCZones *zones // ) { // zones.AddLevelColor( 0.25, clrRed // ); zones.AddLevelColor( 0.20, clrOrange // ); zones.AddLevelColor( 0.15, clrYellow // ); } }; // // Class ... class XSCX121SetupEA : public XSCBaseEA { // // Public ... public: // // Props ... // // Constructors ... XSCX121SetupEA( // // XTrade Class Requirements ... int slippage, // Specify Slippage ulong magicNumber, // Specify Magic Number // // XSCTrade Event Handlers ... TOnSignal onSignal = NULL, // On Signal Recieved Event Handler TOnModify onModifyPosition = NULL, // On Modify Position Event Handler TOnStopLoss onStopLossTriggered = NULL, // On StopLoass Triggered Event Handler TOnTakeProfit onTakeProfitTriggered = NULL, // On TakeProfit Triggered Event Handler TOnForceClose onForceClosePosition = NULL, // On Force Close Position Event Handler TOnPartialClose onPartialClosePosition = NULL, // On Partial Close Position Event Handler TOnDealsChanged onDealsChangedHandler = NULL, // On Deals Changed Event Handler TOnOrdersChanged onOrdersChangedHandler = NULL, // On Orders Changed Event Handler TOnPositionsChanged onPositionsChangedHandler = NULL, // On Positions Changed Event Handler TOnTradeStateChanged onTradeStateChangedHandler = NULL // On Trade State Changed Event Handler ) : XSCBaseEA(slippage, magicNumber, onSignal, onModifyPosition, onStopLossTriggered, onTakeProfitTriggered, onForceClosePosition, onPartialClosePosition, onDealsChangedHandler, onOrdersChangedHandler, onPositionsChangedHandler, onTradeStateChangedHandler // ) { // mTradeHandler = new XTradeHandler(mTrader); // // Implement Default Configs ... DefaultConfigs(); } // // Deconstructor ... ~XSCX121SetupEA() { // delete mTradeHandler; // Clean(mSetups); } // bool AddSetup(XSCX121SetupCycles *setup) { // bool result = false; // result = setup != NULL; if (!result) { return result; } // Add( setup, mSetups // ); // return result; } // // Getter(s) / Setter(s) ... // /// Signals ... // bool AllowLong() { return mAllowLong; } // void AllowLong(bool value) { mAllowLong = value; } // bool AllowShort() { return mAllowShort; } // void AllowShort(bool value) { mAllowShort = value; } // int ReuiredSignalVerifications() { return mReuiredSignalVerifications; } // void ReuiredSignalVerifications(int value) { // if (value < 1) { value = 1; } // mReuiredSignalVerifications = value; } // bool GetVerificationFromOtherTimeFrames() { return mGetVerificationFromOtherTimeFrames; } // void GetVerificationFromOtherTimeFrames(bool value) { mGetVerificationFromOtherTimeFrames = value; } // // Risk Management ... // double Volume() { return mVolume; } // void Volume(double value) { // if (value < 0.01) { value = 0.01; } // mVolume = value; } // double TPPoint() { return mTPPoint; } // void TPPoint(double value) { // if (value < 0) { value = 0; } // mTPPoint = value; } // double SLPoint() { return mSLPoint; } // void SLPoint(double value) { // if (value < 0) { value = 0; } // mSLPoint = value; } // int MaxAllowedTrades() { return mMaxAllowedTrades; } // void MaxAllowedTrades(int value) { // if (value < 0) { value = 0; } // mMaxAllowedTrades = value; // mTrader.SetMaxAllowedPositions(value); } // bool IgnoreTP() { return mIgnoreTP; } // void IgnoreTP(bool value) { mIgnoreTP = value; } // bool IgnoreSL() { return mIgnoreSL; } // void IgnoreSL(bool value) { mIgnoreSL = value; } // // Signalling ... // int StartSignallingHoure() { return mStartSignallingHoure; } // void StartSignallingHoure(int value) { // if (value < -1) { value = -1; } // mStartSignallingHoure = value; } // int EndSignallingHoure() { return mEndSignallingHoure; } // void EndSignallingHoure(int value) { // if (value < -1) { value = -1; } // mEndSignallingHoure = value; } // int CloseOnSpecificTime() { return mCloseOnSpecificTime; } // void CloseOnSpecificTime(int value) { // if (value < -1) { value = -1; } // mCloseOnSpecificTime = value; } // bool CloseOnOpposit() { return mCloseOnOpposit; } // void CloseOnOpposit(bool value) { mCloseOnOpposit = value; } // // Trailling ... // bool AllowTrailStop() { return mTradeHandler.AllowTrailStop(); } // void AllowTrailStop(bool value) { mTradeHandler.AllowTrailStop(value); } // double NextTrailPoint() { return mTradeHandler.NextTrailPoint(); } // void NextTrailPoint(double value) { mTradeHandler.NextTrailPoint(value); } // double FirstTrailPoint() { return mTradeHandler.FirstTrailPoint(); } // void FirstTrailPoint(double value) { mTradeHandler.FirstTrailPoint(value); } // double NextTrailDistance() { return mTradeHandler.NextTrailDistance(); } // void NextTrailDistance(double value) { mTradeHandler.NextTrailDistance(value); } // double FirstTrailDistance() { return mTradeHandler.FirstTrailDistance(); } // void FirstTrailDistance(double value) { mTradeHandler.FirstTrailDistance(value); } // // Supporting ... // bool AllowSupport() { return mTradeHandler.AllowSupport(); } // void AllowSupport(bool value) { mTradeHandler.AllowSupport(value); } // double SupportDistance() { return mTradeHandler.SupportDistance(); } // void SupportDistance(double value) { mTradeHandler.SupportDistance(value); } // int MaxNumberOfSupports() { return mTradeHandler.MaxNumberOfSupports(); } // void MaxNumberOfSupports(int value) { mTradeHandler.MaxNumberOfSupports(value); } // double SupportVolumeMultiplier() { return mTradeHandler.SupportVolumeMultiplier(); } // void SupportVolumeMultiplier(double value) { mTradeHandler.SupportVolumeMultiplier(value); } // double MaxAllowedSupportVolume() { return mTradeHandler.MaxAllowedSupportVolume(); } // void MaxAllowedSupportVolume(double value) { mTradeHandler.MaxAllowedSupportVolume(value); } // // Grid ... // bool AllowGrid() { return mTradeHandler.AllowGrid(); } // void AllowGrid(bool value) { mTradeHandler.AllowGrid(value); } // int MaxNumberOfGrids() { return mTradeHandler.MaxNumberOfGrids(); } // void MaxNumberOfGrids(int value) { mTradeHandler.MaxNumberOfGrids(value); } // double GridDistance() { return mTradeHandler.GridDistance(); } // void GridDistance(double value) { mTradeHandler.GridDistance(value); } // double GridVolumeMultiplier() { return mTradeHandler.GridVolumeMultiplier(); } // void GridVolumeMultiplier(double value) { mTradeHandler.GridVolumeMultiplier(value); } // double MaxAllowedGridVolume() { return mTradeHandler.MaxAllowedGridVolume(); } // void MaxAllowedGridVolume(double value) { mTradeHandler.MaxAllowedGridVolume(value); } // // Recovery System ... // bool AllowRecovery() { return mTradeHandler.AllowRecovery(); } // void AllowRecovery(bool value) { mTradeHandler.AllowRecovery(value); } // int MaxNumberOfRecoveries() { return mTradeHandler.MaxNumberOfRecoveries(); } // void MaxNumberOfRecoveries(int value) { mTradeHandler.MaxNumberOfRecoveries(value); } // double RecoveryDistance() { return mTradeHandler.RecoveryDistance(); } // void RecoveryDistance(double value) { mTradeHandler.RecoveryDistance(value); } // double RecoveryVolumeMultiplier() { return mTradeHandler.RecoveryVolumeMultiplier(); } // void RecoveryVolumeMultiplier(double value) { mTradeHandler.RecoveryVolumeMultiplier(value); } // double MaxAllowedRecoveryVolume() { return mTradeHandler.MaxAllowedRecoveryVolume(); } // void MaxAllowedRecoveryVolume(double value) { mTradeHandler.MaxAllowedRecoveryVolume(value); } // // Others ... // bool SaveResults() { return mTradeHandler.GetSave(); } // void SaveResults(bool value) { mTradeHandler.SetSave(value); } // double ForceCloseProfit() { return mForceCloseProfit; } // void ForceCloseProfit(double value) { // if (value < 0) { value = 0; } // mForceCloseProfit = value; } // bool ForceState() { return mForceState; } // void ForceState(bool value) { mForceState = value; } // // Overrides ... // // Customize Token ... string GetToken() override { return GetSpecificToken(this); } // string GetTag() override { return this.GetToken(); } // // Tools ... // // Check Provider for any Guards ... bool CheckForGuard(XGuard &guards[]) override { // bool result = false; // return result; } // // Request Provider to Collect all // Potentially Signals and then // filters theme here and passed them // for Executing ... int RequestForSignal( XSignal &signals[] // Holds Signals ... ) override { // bool result = 0; // Clean(signals); // if (!IsEnable()) { return result; } // // IMPLEMENT ... int count = CountSetups(); result = IsValidSize(count); if (!result) { return result; } // string separator = "\n"; // // Current ... XSignal cSignal; int cPusher = 0; bool cHasSignal = false; string cProvider = NULL; X121SetupConditions cConditions; // // Short ... XSignal sSignal; int sPusher = 0; bool sHasSignal = false; string sProvider = NULL; X121SetupConditions sConditions; // // Medium ... XSignal mSignal; int mPusher = 0; bool mHasSignal = false; string mProvider = NULL; X121SetupConditions mConditions; // // Long ... XSignal lSignal; int lPusher = 0; bool lHasSignal = false; string lProvider = NULL; X121SetupConditions lConditions; // // Hind ... XSignal hSignal; int hPusher = 0; bool hHasSignal = false; string hProvider = NULL; X121SetupConditions hConditions; // int maxAllowed = MaxAllowedTrades(); X121SignalGenerator signalGenerator; // for (int i = 0; i < count; i++) { // cPusher = 0; sPusher = 0; mPusher = 0; lPusher = 0; hPusher = 0; // cProvider = NULL; sProvider = NULL; mProvider = NULL; lProvider = NULL; hProvider = NULL; // cSignal.Clean(); sSignal.Clean(); mSignal.Clean(); lSignal.Clean(); hSignal.Clean(); // cHasSignal = false; sHasSignal = false; mHasSignal = false; lHasSignal = false; hHasSignal = false; // cConditions.Clean(); sConditions.Clean(); mConditions.Clean(); lConditions.Clean(); hConditions.Clean(); // // Current ... bool canProcess = mSetups[i] .CanProcessBar( X_MARKET_CYCLE_UNKNOWN // ); if (canProcess) { // bool iHasConditions = mSetups[i].GetConditions( cConditions, X_MARKET_CYCLE_UNKNOWN, // Current Market ... 0, // Bar Index ... 5 // Loop Back ... ); // if (!iHasConditions) { continue; } // mVolumeOSC = 0; mBullishSigns = 0; mBullishScore = 0; mBearishSigns = 0; mBearishScore = 0; // // Retrieve Scores ... double bullishScore = 0; double bearishScore = 0; cConditions.GenerateScore( bullishScore, bearishScore // ); mBullishScore += bullishScore; mBearishScore += bearishScore; // mVolumeOSC += cConditions.vlmConditions.volume[1]; // // Parse Conditions for Signal ... cHasSignal = signalGenerator.HasSignal( cConditions, cSignal, cPusher, cProvider, AllowSupport(), mAllowLong, mAllowShort, mVolume, mSLPoint, mIgnoreSL, mTPPoint, mIgnoreTP // ); // if (cHasSignal) { // mSetups[i].WaitsUntilNextBar( X_MARKET_CYCLE_UNKNOWN // ); } } // // Short ... canProcess = mSetups[i] .CanProcessBar( X_MARKET_CYCLE_SHORT // ); if (canProcess) { // bool iHasConditions = mSetups[i].GetConditions( sConditions, X_MARKET_CYCLE_SHORT, // Current Market ... 0, // Bar Index ... 5 // Loop Back ... ); // if (!iHasConditions) { continue; } // // Retrieve Scores ... double bullishScore = 0; double bearishScore = 0; sConditions.GenerateScore( bullishScore, bearishScore // ); mBullishScore += bullishScore; mBearishScore += bearishScore; // mVolumeOSC += sConditions.vlmConditions.volume[1]; // // Parse Conditions for Signal ... sHasSignal = signalGenerator.HasSignal( sConditions, sSignal, sPusher, sProvider, AllowSupport(), mAllowLong, mAllowShort, mVolume, mSLPoint, mIgnoreSL, mTPPoint, mIgnoreTP // ); // if (sHasSignal) { // mSetups[i].WaitsUntilNextBar( X_MARKET_CYCLE_SHORT // ); } } // // Medium ... canProcess = mSetups[i] .CanProcessBar( X_MARKET_CYCLE_MEDIUM // ); if (canProcess) { // bool iHasConditions = mSetups[i].GetConditions( mConditions, X_MARKET_CYCLE_MEDIUM, // Current Market ... 0, // Bar Index ... 5 // Loop Back ... ); // if (!iHasConditions) { continue; } // // Retrieve Scores ... double bullishScore = 0; double bearishScore = 0; mConditions.GenerateScore( bullishScore, bearishScore // ); mBullishScore += bullishScore; mBearishScore += bearishScore; // mVolumeOSC += mConditions.vlmConditions.volume[1]; // // Parse Conditions for Signal ... mHasSignal = signalGenerator.HasSignal( mConditions, mSignal, mPusher, mProvider, AllowSupport(), mAllowLong, mAllowShort, mVolume, mSLPoint, mIgnoreSL, mTPPoint, mIgnoreTP // ); // if (mHasSignal) { // mSetups[i].WaitsUntilNextBar( X_MARKET_CYCLE_MEDIUM // ); } } // // Long ... canProcess = mSetups[i] .CanProcessBar( X_MARKET_CYCLE_LONG // ); if (canProcess) { // bool iHasConditions = mSetups[i].GetConditions( lConditions, X_MARKET_CYCLE_LONG, // Current Market ... 0, // Bar Index ... 5 // Loop Back ... ); // if (!iHasConditions) { continue; } // // Retrieve Scores ... double bullishScore = 0; double bearishScore = 0; lConditions.GenerateScore( bullishScore, bearishScore // ); mBullishScore += bullishScore; mBearishScore += bearishScore; // mVolumeOSC += lConditions.vlmConditions.volume[1]; // // Parse Conditions for Signal ... lHasSignal = signalGenerator.HasSignal( lConditions, lSignal, lPusher, lProvider, AllowSupport(), mAllowLong, mAllowShort, mVolume, mSLPoint, mIgnoreSL, mTPPoint, mIgnoreTP // ); // if (lHasSignal) { // mSetups[i].WaitsUntilNextBar( X_MARKET_CYCLE_LONG // ); } } // // Hind ... canProcess = mSetups[i] .CanProcessBar( X_MARKET_CYCLE_HIND // ); if (canProcess) { // bool iHasConditions = mSetups[i].GetConditions( hConditions, X_MARKET_CYCLE_HIND, // Current Market ... 0, // Bar Index ... 5 // Loop Back ... ); // if (!iHasConditions) { continue; } // // Retrieve Scores ... double bullishScore = 0; double bearishScore = 0; hConditions.GenerateScore( bullishScore, bearishScore // ); mBullishScore += bullishScore; mBearishScore += bearishScore; // mVolumeOSC += hConditions.vlmConditions.volume[1]; // // Parse Conditions for Signal ... hHasSignal = signalGenerator.HasSignal( hConditions, hSignal, hPusher, hProvider, AllowSupport(), mAllowLong, mAllowShort, mVolume, mSLPoint, mIgnoreSL, mTPPoint, mIgnoreTP // ); // if (hHasSignal) { // mSetups[i].WaitsUntilNextBar( X_MARKET_CYCLE_HIND // ); } } // // Parse Signals and Add them for Executing ... // // Check if there is a Signal or Not ... bool hasSignal = cHasSignal || sHasSignal || mHasSignal || lHasSignal || hHasSignal; if (hasSignal) { // // Handle Creating a new Signal Info ... XSignal signal; X121SetupConditions otherConditions[]; if (hHasSignal) { // signal = hSignal; // AddRef( cConditions, otherConditions // ); AddRef( sConditions, otherConditions // ); } else if (lHasSignal) { // signal = lSignal; // AddRef( cConditions, otherConditions // ); AddRef( sConditions, otherConditions // ); AddRef( mConditions, otherConditions // ); } else if (mHasSignal) { // signal = mSignal; // AddRef( cConditions, otherConditions // ); AddRef( sConditions, otherConditions // ); } else if (sHasSignal) { // signal = sSignal; // AddRef( cConditions, otherConditions // ); AddRef( mConditions, otherConditions // ); AddRef( lConditions, otherConditions // ); AddRef( hConditions, otherConditions // ); } else if (cHasSignal) { // signal = cSignal; // AddRef( sConditions, otherConditions // ); AddRef( mConditions, otherConditions // ); AddRef( lConditions, otherConditions // ); AddRef( hConditions, otherConditions // ); } // int pushers = cPusher + sPusher + mPusher + lPusher + hPusher; // bool isLong = IsLong(signal.type); // // Collecting Bullish/Bearish Signs ... if (isLong) { mBullishSigns += pushers; } else { mBearishSigns += pushers; } // // Validate Signal ... bool isValid = // // Handle Pusher Validations ... (mReuiredSignalVerifications <= 0 ? true : pushers >= mReuiredSignalVerifications) // && // // Handle Other Conditions Validations ... (!mGetVerificationFromOtherTimeFrames ? true : isLong ? signalGenerator.HasLongVerifications(otherConditions) : signalGenerator.HasShortVerifications(otherConditions)) // ; // bool forceState = ForceState(); // if (!isValid || (forceState && isValid)) { // // Clear Other Conditions ... Clean(otherConditions); // // Fill All Conditions to Other Conditions ... AddRef( cConditions, otherConditions // ); AddRef( sConditions, otherConditions // ); AddRef( mConditions, otherConditions // ); AddRef( lConditions, otherConditions // ); AddRef( hConditions, otherConditions // ); // // If Recieved Any Unverified Signal // we Passed it to EQM Manager ... EQMHandleInvalidSignal( signal, pushers, mVolumeOSC, mBullishScore, mBullishSigns, mBearishScore, mBearishSigns, otherConditions, isValid // ); continue; } // if (!forceState) { // // Add Signal to Execution Result ... AddRef( signal, signals // ); // // Add new Signal Info ... mTradeHandler.Add( signal, pushers, mVolumeOSC, mBullishSigns, mBearishSigns, mBullishScore, mBearishScore, cConditions, sConditions, mConditions, lConditions, hConditions // ); } } } // // // // Create Score Summary for Commenting on Chart ... // string scoreSummary = // // // "----------" + separator + // "Bullish Score: " + ToString(mBullishScore) + separator + // "Bullish Signs: " + ToString(mBullishSigns) + separator + // "----------" + separator + // "Bearish Score: " + ToString(mBearishScore) + separator + // "Bearish Signs: " + ToString(mBearishSigns) + separator + // "----------" + separator + // "Volume: " + ToString(mVolumeOSC) + separator + // "DrawDown: " + ToString(GetDrawdownPercent()) + "%" + // "" // // // ; // // // Comment(scoreSummary); // result = ArraySize(signals); // return result; } // // Here we Manage Signals for Executing ... // - Check Policies based on their Signaller ... // - Check Same Time Open Positions ... // - Check Signal Age for new Trade ... // and etc ... int HandleSignalManagement(XSignal &signals[]) override { // int result = 0; // int signalsCount = ArraySize(signals); if (!IsValidSize(signalsCount)) { return result; } // XSignal tmpSignals[]; XSignal eSignals[]; // Must Executed Copy( signals, tmpSignals // ); // Clean(signals); // int maxAllowed = MaxAllowedTrades(); // for (int i = 0; i < signalsCount; i++) { // XSignal iSignal = tmpSignals[i]; // bool isSignalValid = false; // // Handle Close All Positions when Opposit Signal Recieved ... if (mCloseOnOpposit) { // // Select Signal Opposit Positions ... ENUM_X_POSITION_TYPES iOpposit = GetOppositPositionType(iSignal.type); // XPosition iPositions[]; int iPositionsCount = mTrader.GetPositions( iPositions, iSignal.symbol, NULL, // All Providers ... NULL, // All Periods ... iOpposit // Opposit Positions ... ); // if (IsValidSize(iPositionsCount)) { // string comment = "Close due Opposit ..."; // int closeds = Close( iPositions, comment // ); if (IsValidSize(closeds)) { // string message = XEQMSupportToken + " Closed " + ToString(iPositionsCount) + " due Opposit Signal ..."; // Alert(message); } } } // // TODO: Remove this ... // isSignalValid = !AllowSupport() // ? true // : IsValidSize(ArraySize(iSignal.supports)); // if (!isSignalValid) // { // continue; // } // // Filter Signals Based On Max Allowed ... if (maxAllowed > 0) { // XPosition iSymbolsPositions[]; int iSymbolsPositionsCount = mTrader.GetPositions( iSymbolsPositions, iSignal.symbol, NULL, NULL, NULL, true // ); // int iSupportsCount = 0; if (IsValidSize(iSymbolsPositionsCount)) { // // Filter Support Positions ... XPosition iSupports[]; iSupportsCount = ExtractSupports( iSymbolsPositions, iSupports // ); } // isSignalValid = iSupportsCount <= 0 ? iSymbolsPositionsCount < maxAllowed : iSymbolsPositionsCount - iSupportsCount < maxAllowed; if (!isSignalValid) { continue; } } else { isSignalValid = true; } // if (isSignalValid) { // AddRef( iSignal, eSignals // ); } } // // Cutom Signal Execution ... HandleSignals(eSignals); // result = ArraySize(signals); // return result; } // // Handle State Management .... // here we can manage current state ... // - Check for Long Positions for each Signaller to Close ... // - Handle Hedging Signaller's Positions if it's enabled ... // - Force Closing Position when Specified Time reached ... // - Check Start and End time or Trading Dates ... // - handle Trailing or Risk free Signals based on several conditions ... // and etc ... bool HandleStateManagement(XSignal &signals[]) override { // const bool result = false; // // Do all State Management here ... // DoHedge(); // DoEQMForceClose(); // // Handle Close All Positions on Specific Time ... DoEQMCloseOnSpecificTime(); // // Do EQM Protection if Provided ... DoEQMProtect(); // // if Returns true, Signal Execution failed ... return result; } // // Signal Info ... // void OnSignalExecuted(const XSignal &signal) override { // // Signal Info Manager ... XSignal tSignal = signal; bool isSupport = IsSupport(signal.comment); if (!isSupport) { mTradeHandler.Update(tSignal); } // mTradeHandler.Sync(); } // void OnSignalExecutionFailed( const XSignal &signal, const ENUM_X_SIGNAL_EXECUTION_RESULT reason // ) override { // // Signal Info Manager ... XSignal tSignal = signal; mTradeHandler.Remove(tSignal); mTradeHandler.Sync(); } // void OnPositionClosed( const XPosition &position, const string comment // ) override { // // When a Position Closed Manually ... // Signal Info Manager ... XPosition tPosition = position; bool isSupport = ExtractSupportedTicket(position.comment) > 0; bool isEQMSupport = ExtractEQMSupportedTicket(position.comment) > 0; tPosition.comment = comment; if (!isSupport && !isEQMSupport) { mTradeHandler.Update(tPosition); } // mTradeHandler.Sync(); } // void OnStopLossTriggered(const XDeal &deal) override { // // When a Position's Stop Loss Triggered ... // Signal Info Manager ... XDeal tDeal = deal; mTradeHandler.Update(tDeal); mTradeHandler.Sync(); } // void OnTakeProfitTriggered(const XDeal &deal) override { // // When a Position's Take Profit Triggered ... // Signal Info Manager ... XDeal tDeal = deal; mTradeHandler.Update(tDeal); mTradeHandler.Sync(); } // // Protected ... protected: // // Tools ... // // Check Signalling Enable or not ... bool IsEnable() { // bool result = false; // // Check Signal Type is Enabled or not ... bool isTypePassed = mAllowLong || mAllowShort; // // Check Signalling Time ... MqlDateTime cTime; bool isTimeRecieved = TimeCurrent(cTime); // int endHour = EndSignallingHoure(); int startHour = StartSignallingHoure(); // bool isStartHourPassed = startHour <= -1 ? true : cTime.hour >= startHour; bool isEndHourPassed = endHour <= -1 ? true : cTime.hour < endHour; bool isTimePassed = isTimeRecieved && isStartHourPassed && isEndHourPassed; // result = isTypePassed && isTimePassed; // return result; } // bool CanCloseOnTime() { // bool result = false; // result = mCloseOnSpecificTime >= 0 && mCloseOnSpecificTime <= 23; if (!result) { return result; } // MqlDateTime timeStruct; result = TimeCurrent(timeStruct); if (!result) { return result; } // result = timeStruct.hour == mCloseOnSpecificTime; // return result; } // // Custom Signal Execution ... void HandleSignals(XSignal &signals[]) { // int signalsCount = ArraySize(signals); if (!IsValidSize(signals)) { return; } // ENUM_X_SIGNAL_EXECUTION_RESULT states[]; int executedSignalsCount = ExecuteSignals( signals, states, false // ); } // // Private ... private: // // Props ... // // Signals ... bool mAllowLong; // Allow Long bool mAllowShort; // Allow Short double mForceCloseProfit; // Close All Positions Regardless of Policies when Profit Reached int mReuiredSignalVerifications; // Required Verifications for Validate Signals bool mGetVerificationFromOtherTimeFrames; // Get Verifications from Other Time Frames // // Risk Management ... double mVolume; // Volume double mTPPoint; // TP Point double mSLPoint; // SL Point int mMaxAllowedTrades; // Max Alloed Positions bool mIgnoreTP; // Ignore Calculated TP bool mIgnoreSL; // Ignore Calculated SL // // Signalling ... bool mCloseOnOpposit; // Close all Positions on Opposit int mEndSignallingHoure; // End Signalling at Specific Time int mCloseOnSpecificTime; // Close All Trades in Specific Time int mStartSignallingHoure; // Start Signalling at Specific Time // // Force State: // we can do many things in force state: // - Prepare Force Hedging; // - Receive Signals with minimal Verifications; // - Increase Volume Size of in Profit Positions; // - etc ... bool mForceState; // Determine in Force State or not // XTradeHandler *mTradeHandler; // Handle all Event which related to Signals and Positions // // Apply Default Configurations ... void DefaultConfigs() { // // Signals ... AllowLong(false); AllowShort(false); ReuiredSignalVerifications(0); GetVerificationFromOtherTimeFrames(false); // // Risk Management ... TPPoint(0); SLPoint(0); Volume(0.01); IgnoreTP(false); IgnoreSL(false); MaxAllowedTrades(0); // // Signalling ... CloseOnOpposit(false); EndSignallingHoure(-1); CloseOnSpecificTime(-1); StartSignallingHoure(-1); // // Trailling ... AllowTrailStop(false); NextTrailPoint(0); FirstTrailPoint(0); NextTrailDistance(0); FirstTrailDistance(0); // // Supporting ... AllowSupport(false); MaxNumberOfSupports(0); SupportVolumeMultiplier(0.01); MaxAllowedSupportVolume(0.08); // // Grid ... AllowGrid(false); GridDistance(0); MaxNumberOfGrids(0); GridVolumeMultiplier(0.01); MaxAllowedGridVolume(0.08); // // Recovery ... AllowRecovery(false); MaxNumberOfRecoveries(0); RecoveryDistance(0); RecoveryVolumeMultiplier(0.01); MaxAllowedRecoveryVolume(0.08); // SaveResults(false); } // int mBullishSigns; double mBullishScore; // int mBearishSigns; double mBearishScore; // double mVolumeOSC; // XSCX121SetupCycles *mSetups[]; // Number of Setups // // Tools ... int CountSetups() { return ArraySize(mSetups); } // int FindSetupIndex( string symbol, ENUM_TIMEFRAMES period // ) { // int result = -1; // int count = CountSetups(); if (!IsValidSize(count)) { return result; } // for (int i = 0; i < count; i++) { // XSCX121SetupCycles *iSetup = mSetups[i]; // X121SetupInputs iInputs = iSetup.GetInputs(); // if (iInputs.symbol == symbol && iInputs.period == period) { // result = i; break; } } // return result; } // int FindSetupIndex( string symbol // ) { // int result = -1; // int count = CountSetups(); if (!IsValidSize(count)) { return result; } // for (int i = 0; i < count; i++) { // XSCX121SetupCycles *iSetup = mSetups[i]; // X121SetupInputs iInputs = iSetup.GetInputs(); // if (iInputs.symbol == symbol) { // result = i; break; } } // return result; } // // EQM Functions ... // bool DoEQMForceClose( double requiredProfit = 0 // Required Profit For EQM Force Hedge ... ) { // bool result = false; // double hedgingProfit = requiredProfit == 0 ? mForceCloseProfit : requiredProfit; bool canDo = hedgingProfit > 0; if (!canDo) { return result; } // XPosition positions[]; int positionsCount = mTrader.GetPositions(positions); result = IsValidSize(positionsCount); if (!result) { return result; } // double profit = SpecifiedIsPositionsReadyForHedge( positions, 0.15, 0.01 // ); result = profit > hedgingProfit; if (!result) { return result; } // string comment = XEQMSupportToken + " Hedge ..."; int closed = Close( positions, comment // ); // result = IsValidSize(closed); // // Handle Sleeping ... int restingTime = RestingAfterHedge(); if (result && IsValidSize(restingTime)) { Sleep(restingTime * 1000); } // return result; } // // Do Gridding Mechanism ... void DoEQMProtect() { // // Check if there are open Positions // and their doesn't have TP and SL and // Youngest Age of Positions longest as enough // Make State of Signalling to Force State for Recieving // Signal and Clear their Tp and SL for allowing hedges ... EQMHandleForceState(); // XSignal supports[]; int supportsCount = mTradeHandler.DoProtect( supports, mSetups, ForceState() // ); // if (IsValidSize(supportsCount)) { EQMExecuteSignals(supports); } } // // Handle Close Trades on Specific Time ... void DoEQMCloseOnSpecificTime() { // bool canClose = CanCloseOnTime(); if (!canClose) { return; } // XPosition positions[]; int positionsCount = mTrader.GetPositions(positions); if (!IsValidSize(positionsCount)) { return; } // string comment = XEQMSupportToken + " Close On Specific Time ..."; // int closed = Close( positions, comment // ); if (IsValidSize(closed)) { // string message = XEQMSupportToken + " Closed " + ToString(closed) + " Positions on Specified Time ..."; // Alert(message); } } // // Handle Force State Management ... void EQMHandleForceState() { // XPosition positions[]; int positionsCount = mTrader.GetPositions(positions); if (!IsValidSize(positionsCount)) { // // Disable Force State if there isn't any open Positions // and it's Enabled ... // this means Hedged positions ... if (ForceState()) { ForceState(false); } // return; } // // Checking Force Sate Conditions ... if (ForceState()) { // // Check Force State Hedging ... // bool isHedged = DoEQMForceClose(); // if (isHedged) // { // // // ForceState(false); // return; // } // // // isHedged = DoEQMForceClose(5); // if (isHedged) // { // // // ForceState(false); // return; // } // // return; } // int longs = 0; double longVolumes = 0; double longProfits = 0; // int shorts = 0; double shortVolumes = 0; double shortProfits = 0; // // Retrieve Required Informations of Positions ... CountPositions( positions, longs, longProfits, longVolumes, shorts, shortProfits, shortVolumes // ); // // Retrieve Youngest Age ... XPosition youngest; int youngestAge = GetYoungest( youngest, positions // ); // // Now Comparing items for enabling force State ... bool isForceState = // youngestAge >= 20 && // (longProfits + shortProfits < 0) // ; if (isForceState) { // ForceState(true); // return; } // XPosition supports[]; int supportsCount = ExtractSupports( positions, supports // ); if (!IsValidSize(supportsCount)) { return; } // int maxSupports = mTradeHandler.EnableSupport() ? MaxNumberOfSupports() : 0; int maxGrids = mTradeHandler.EnableGrid() ? MaxNumberOfGrids() : 0; int maxRecoveries = mTradeHandler.EnableRecovery() ? MaxNumberOfRecoveries() : 0; // // Supporting Force States ... bool isProtectionForce = supportsCount >= 1; if (isProtectionForce) { // ForceState(true); // return; } // } // // Handle any Invalid Signals ... void EQMHandleInvalidSignal( XSignal &signal, // Invalid Signal int pushers, // Pushers double volumeOSC, // Volume Summary of Signal double bullishScore, // Bullish Score Summary int bullishSigns, // Number of Bullish Signs double bearishScore, // Bearish Score Summary int bearishSigns, // Number of Bearish Signs X121SetupConditions &conditions[], // All Time Frames Conditions bool isValid = false // IsValid Signal ... ) { // // Check Force State ... if (!ForceState()) { return; } // // TODO: Implement it ... // XSignal signals[]; // if (isValid) { // AddRef( signal, signals // ); } // if (ArraySize(signals) > 0) { EQMExecuteSignals(signals); } } // void EQMExecuteSignals( XSignal &signals[] // ) { // int signalsCount = ArraySize(signals); if (!IsValidSize(signals)) { return; } // // // Execute Supports ... ENUM_X_SIGNAL_EXECUTION_RESULT states[]; int executed = ExecuteSignals( signals, states, false // Ignore Policies ... ); if (executed != signalsCount) { // // TODO: Dow What We Want ... // Print("Error On Executing Support Signal ..."); } // // Remove Supported Signals TP and SL and leave them for Handling using HEDGE Mechanism ... if (IsValidSize(executed)) { // for (int i = 0; i < signalsCount; i++) { // ENUM_X_SIGNAL_EXECUTION_RESULT iState = states[i]; if (iState != X_SIGNAL_EXECUTION_SUCCEED) { continue; } // XSignal iSignal = signals[i]; if (!iSignal.IsValid() || !iSignal.IsExecuted()) { continue; } // ulong iParentTicket = ExtractParentTicket(iSignal.comment); if (iParentTicket <= 0) { continue; } // XPosition iParent; bool hasParent = mTrader.GetPosition( iParentTicket, iParent // ); if (!hasParent) { continue; } // // Check Parent Has TP or SL ... if (iParent.tp == 0 && iParent.sl == 0) { continue; } // // Remove TP and SL of Supported Positions ... string comment = "EQM Remove TPSL ..."; bool isModified = Modify( iParentTicket, 0, 0, comment // ); if (isModified) { // // TODO: // do What we want ... } } } } // }; //