/////////////////////////////////////////////////////// // // 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_TYPE 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(); } // 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; // 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 ... // // Grid System Calculations ... // double gEntry; // Represents Next Grid Signal's Entry double gVolume; // Represent Next Grid Signal's Volume // void ResetGrid() { gEntry = 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 // ); } // 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 XTradeInfoHandler { // public: // // Props ... // // Constructor ... void XTradeInfoHandler( XSCTrade *trade // an Instance of Trader Class ) { // Clean(data); SetSave(false); mTrader = trade; collector = new XTradeInfoCollector(); } // // Getter(s) / Setter(s) ... // bool GetSave() { return mSave; } // void SetSave(bool value) { mSave = value; } // // Grid System ... // bool AllowGrid() { return mAllowGrid; } // void AllowGrid(bool value) { mAllowGrid = 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 = 0; } // mGridVolumeMultiplier = value; } // // Check Grid Properties to Validate it's Enable or not ... bool EnableGrid() { // bool result = false; // result = // AllowGrid() && GridDistance() > 0 && GridVolumeMultiplier() > 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() // ); } } // 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); } // // Grid System Tools ... int RequestForGrid(XSignal &signals[]) { // int result = 0; // Clean(signals); // if (!EnableGrid()) { return result; } // int count = Count(); if (!IsValidSize(count)) { return result; } // for (int i = 0; i < count; i++) { // XSignal iSignal; bool hasGrid = data[i].HasGrid( iSignal, GridDistance(), GridVolumeMultiplier() // ); // if (hasGrid) { // AddRef( iSignal, signals // ); } } // result = ArraySize(signals); // return result; } // // Protected ... protected: // // Props ... XSCTrade *mTrader; XTradeInfo data[]; XTradeInfoCollector *collector; // bool mSave; // Save Results ... // // Tools ... // void Finish(int index) { // XTradeInfo info = data[index]; if (!info.IsValid()) { return; } // ArrayRemove( data, index, 1 // ); // if (GetSave()) { collector.Save(info); } } // // Grid ... bool mAllowGrid; // Use Grid System to Recovery Positions double mGridDistance; // Grid System Distance double mGridVolumeMultiplier; // Grid System Volume Multiplier }; // // 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 // ) { // mTradeInfoHandler = new XTradeInfoHandler(mTrader); SaveResults(false); } // // Deconstructor ... ~XSCX121SetupEA() { // delete mTradeInfoHandler; // 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) ... // bool AllowLong() { return mAllowLong; } // void AllowLong(bool value) { mAllowLong = value; } // bool AllowShort() { return mAllowShort; } // void AllowShort(bool value) { mAllowShort = value; } // 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; } // bool IgnoreTP() { return mIgnoreTP; } // void IgnoreTP(bool value) { mIgnoreTP = value; } // bool IgnoreSL() { return mIgnoreSL; } // void IgnoreSL(bool value) { mIgnoreSL = value; } // bool CloseOnOpposit() { return mCloseOnOpposit; } // void CloseOnOpposit(bool value) { mCloseOnOpposit = 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; } // int MaxAllowedTrades() { return mMaxAllowedTrades; } // void MaxAllowedTrades(int value) { // if (value < 0) { value = 0; } // mMaxAllowedTrades = value; mTrader.SetMaxAllowedPositions(value); } // int CloseOnSpecificTime() { return mCloseOnSpecificTime; } // void CloseOnSpecificTime(int value) { // if (value < 0) { value = -1; } // if (value > 23) { value = 23; } // mCloseOnSpecificTime = value; } // bool UseSupport() { return mUseSupport; } // void UseSupport(bool value) { mUseSupport = value; } // bool AllowGrid() { return mTradeInfoHandler.AllowGrid(); } // void AllowGrid(bool value) { mTradeInfoHandler.AllowGrid(value); } // double GridDistance() { return mTradeInfoHandler.GridDistance(); } // void GridDistance(double value) { mTradeInfoHandler.GridDistance(value); } // double GridVolumeMultiplier() { return mTradeInfoHandler.GridVolumeMultiplier(); } // void GridVolumeMultiplier(double value) { mTradeInfoHandler.GridVolumeMultiplier(value); } // bool SaveResults() { return mTradeInfoHandler.GetSave(); } // void SaveResults(bool value) { mTradeInfoHandler.SetSave(value); } // // Overrides ... // // Customize Token ... string GetToken() override { return GetSpecificToken(this); } // string GetTag() override { return this.GetToken(); } // // 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; // 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, mUseSupport, 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, mUseSupport, 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, mUseSupport, 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, mUseSupport, 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, mUseSupport, 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)) // ; // if (!isValid) { continue; } // // Add Signal to Execution Result ... AddRef( signal, signals // ); // // Add new Signal Info ... mTradeInfoHandler.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[]; Copy( signals, tmpSignals // ); // Clean(signals); // for (int i = 0; i < signalsCount; i++) { // XSignal iSignal = tmpSignals[i]; // // Handle Close All Positions when Opposit Signal Recieved ... if (mCloseOnOpposit) { // // Select Signal Opposit Positions ... ENUM_X_POSITION_TYPE 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); } } } // AddRef( iSignal, signals // ); } // 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 ... // DoEQMHedge(); // // Handle Close All Positions on Specific Time ... DoEQMCloseOnSpecificTime(); // // Do EQM Grid if Provided ... DoEQMGrid(); // // if Returns true, Signal Execution failed ... return result; } // // Signal Info ... // void OnSignalExecuted(const XSignal &signal) override { // // Signal Info Manager ... XSignal tSignal = signal; mTradeInfoHandler.Update(tSignal); } // void OnSignalExecutionFailed( const XSignal &signal, const ENUM_X_SIGNAL_EXECUTION_RESULT reason // ) override { // // Signal Info Manager ... XSignal tSignal = signal; mTradeInfoHandler.Remove(tSignal); } // void OnPositionClosed( const XPosition &position, const string comment // ) override { // // When a Position Closed Manually ... // Signal Info Manager ... XPosition tPosition = position; tPosition.comment = comment; mTradeInfoHandler.Update(tPosition); } // void OnStopLossTriggered(const XDeal &deal) override { // // When a Position's Stop Loss Triggered ... // Signal Info Manager ... XDeal tDeal = deal; mTradeInfoHandler.Update(tDeal); } // void OnTakeProfitTriggered(const XDeal &deal) override { // // When a Position's Take Profit Triggered ... // Signal Info Manager ... XDeal tDeal = deal; mTradeInfoHandler.Update(tDeal); } // // Protected ... protected: // // Tools ... // bool IsEnable() { return mAllowLong || mAllowShort; } // 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; } // // Private ... private: // // Props ... // bool mAllowLong; // Allow Long bool mAllowShort; // Allow Short double mVolume; // Volume double mTPPoint; // TP Point double mSLPoint; // SL Point bool mIgnoreTP; // Ignore Calculated TP bool mIgnoreSL; // Ignore Calculated SL int mMaxAllowedTrades; // Max Alloed Positions bool mCloseOnOpposit; // Close all Positions on Opposit int mCloseOnSpecificTime; // Close All Trades in Specific Time int mReuiredSignalVerifications; // Required Verifications for Validate Signals bool mGetVerificationFromOtherTimeFrames; // Get Verifications from Other Time Frames // bool mUseSupport; // Use Support Signals // bool mSaveResults; // Save Results in Specific Structure for Test Purposes ... XTradeInfoHandler *mTradeInfoHandler; // Handle all Event which related to Signals and Positions // 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; } // // EQM Functions ... // bool EnableGrid() { return mTradeInfoHandler.EnableGrid(); } // // Remove Untriggered EQM Orders ... void RemoveEQMOrders() { // RemoveDraws("XTRND"); // XOrder supports[]; int supportsCount = mTrader.GetOrders( supports, NULL, // All Symbols ... XEQMSupportToken, // Only EQM Supports ... NULL, // All Periods ... X_POSITION_TYPE_ALL, // All Order Types ... ORDER_STATE_PLACED, // Untriggered Orders ... true // Filter by Magic ... ); if (!IsValidSize(supportsCount)) { return; } // int cancelled = mTrader.CancelOrders( supports // ); // if (IsValidSize(cancelled)) { // string message = XEQMSupportToken + " Cancel " + ToString(cancelled) + " Supports ..."; // Alert(message); } } // // Place EQM Orders ... void PlaceEQMOrders() { // int count = CountSetups(); if (!IsValidSize(count)) { return; } // XSignal supports[]; // for (int i = 0; i < count; i++) { // string iSymbol = mSetups[i].GetSymbol(); ENUM_TIMEFRAMES iPeriod = NULL; // All Periods ... string iProvider = NULL; // All Providers ... // XPosition iPositions[]; int iPositionsCount = mTrader.GetPositions( iPositions, iSymbol, iProvider, iPeriod, X_POSITION_TYPE_ALL // ); if (!IsValidSize(iPositionsCount)) { continue; } // int maxInDIDX = FindMaxDrawdownIndex( iPositions // ); if (!IsValidIndex(maxInDIDX)) { continue; } // XPosition maxInDP = iPositions[maxInDIDX]; bool isLong = IsLong(maxInDP.type); // XOHCL iZBar; bool isInited = iZBar.Init( iSymbol, iPeriod, 0 // ); if (!isInited) { continue; } // double iSupport = 0; double iResistance = 0; bool isDrawn = DrawTrendState( ChartID(), "XTRND", iZBar, iSupport, iResistance // ); if (isDrawn) { // XSignal iSignal; // double iSL = 0; double iTP = 0; double iEntry = 0; ENUM_POSITION_TYPE iType; ENUM_X_ORDER_MODES iMode; double iVolume = maxInDP.volume * 3; // if (iSupport > 0 && isLong && iSupport > maxInDP.sl && maxInDP.sl > 0) { // // Add Short Support for Long ... iEntry = iSupport; iSL = maxInDP.tp; iTP = maxInDP.sl; iMode = X_ORDER_MODE_STOP; iType = POSITION_TYPE_SELL; // bool isPrepared = iSignal.Prepare( iSymbol, XEQMSupportToken, iPeriod, iType, iMode, iEntry, iVolume, iSL, iTP // ); if (isPrepared) { // iSignal.comment = GenerateSupportTag(maxInDP.ticket); // AddRef( iSignal, supports /// ); // iSignal.Clean(); } } // if (iResistance > 0 && !isLong && iResistance < maxInDP.sl && maxInDP.sl > 0) { // // Add Long Support for Short ... iEntry = iResistance; iSL = maxInDP.tp; iTP = maxInDP.sl; iMode = X_ORDER_MODE_STOP; iType = POSITION_TYPE_BUY; // bool isPrepared = iSignal.Prepare( iSymbol, XEQMSupportToken, iPeriod, iType, iMode, iEntry, iVolume, iSL, iTP // ); if (isPrepared) { // iSignal.comment = GenerateSupportTag(maxInDP.ticket); // AddRef( iSignal, supports /// ); // iSignal.Clean(); } } } } // int supportsCount = ArraySize(supports); if (!IsValidSize(supportsCount)) { return; } // ENUM_X_SIGNAL_EXECUTION_RESULT states[]; int executeds = mTrader.ExecuteSignals( supports, states, ORDER_TIME_GTC, false, false // Ignore Policies ); if (IsValidSize(executeds)) { // string message = XEQMSupportToken + " Execute " + ToString(executeds) + " Supports ..."; // Alert(message); } } // // Do Gridding Mechanism ... void DoEQMGrid() { // if (!EnableGrid()) { return; } // XSignal signals[]; int signalsCount = mTradeInfoHandler .RequestForGrid(signals); if (!IsValidSize(signalsCount)) { return; } // // Execute Supports ... ENUM_X_SIGNAL_EXECUTION_RESULT states[]; int executed = ExecuteSignals( signals, states, false // Ignore Policies ... ); } // // 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); } } }; //