/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // ---------------------------------------------- // Name: XSCX121EA // Description: an Expert Class which // used X121 Setup ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://www.saherelm.ir" #property version "1.00" #property strict // // START Import and Inclused requirements ... // // // Includes ... #include "../Classes/x-saherelm.xea.class.mq5" #include "../Libraries/x-saherelm.x121.draw.lib.mq5" #include "../Classes/x-saherelm.x121.provider.class.mq5" // // END Import and Inclused requirements ... // // // START Definitions ... // // // END Definitions ... // // // START Overrides ... // // // END Overrides ... // // // an Expert Advisor Class by X121Provider ... class XSCX121EA : public XSCBaseEA { // // Public ... public: // // Props ... // // Constructor ... void XSCX121EA( string symbol, // Trading Symbol ENUM_TIMEFRAMES period, // Trading Time Frame ulong magic, // Magic Number int slippage, // Slippgae double maxAllowedSpread = 0, // Max Allowed Spread to Execute Signal int maxAllowedPositions = 0, // Maximum Allowed Same Time Position double minProfitPerTrade = 0, // Min Profit Per Trade based On Volume Factor (Hedge) double minProfitPerVolumeFactor = 0, // Min Volume Factor for Calculating Profit (Hedge) double maxAllowedDrawDownFactor = 0, // Max Allowed Drawdown factor for Open New Positions TOnStopLoss onStopLossTriggered = NULL, // On StopLoass Triggered Event Handler TOnTakeProfit onTakeProfitTriggered = NULL, // On TakeProfit Triggered 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 TOnSignalConditions onSignalConditions = NULL // On SignalConditions Event Handler ) : XSCBaseEA(symbol, period, magic, slippage, maxAllowedSpread, maxAllowedPositions, minProfitPerTrade, minProfitPerVolumeFactor, maxAllowedDrawDownFactor, onStopLossTriggered, onTakeProfitTriggered, onDealsChangedHandler, onOrdersChangedHandler, onPositionsChangedHandler, onTradeStateChangedHandler) { mOnSignalConditions = onSignalConditions; } // // DeConstructor ... void ~XSCX121EA() { // // Delete All Registered Providers ... int providersCount = ArraySize(mProviders); if (providersCount > 0) { // for (int i = 0; i < providersCount; i++) { // X121SignalProvider iProvider = mProviders[i]; // delete iProvider.provider; } } } // // START Properties ... // // // Min Profit Per Trade ... // bool MinProfitPerTrade(double value) { // bool result = false; // if (value <= 0) { return result; } // result = value > 0; if (value == mMinProfitPerTrade) { return result; } // mMinProfitPerTrade = value; // return result; } // double MinProfitPerTrade() { return mMinProfitPerTrade; } // // Min Profit Per Volume Factor ... // bool MinProfitPerVolumeFactor(double value) { // bool result = false; // if (value <= 0) { return result; } // result = value > 0; if (value == mMinProfitPerVolumeFactor) { return result; } // mMinProfitPerVolumeFactor = value; // return result; } // double MinProfitPerVolumeFactor() { return mMinProfitPerVolumeFactor; } // // Add Provider ... bool AddProvider( X121SignalProvider &provider // Specific Provider ... ) { // bool result = false; // // Validate Provider ... if (provider.symbol == NULL || provider.period == NULL || provider.riskAmount <= 0 || StringLen(provider.symbol) == 0 || ArraySize(provider.providers) == 0) { return result; } // // Check Exists or not ... int idx = GetProviderIndex( provider.symbol, provider.period); if (idx >= 0) { return result; } // PrepareProviderConfig(); // // Make Instance of X121Provider Class ... provider.provider = new XSCX121Provider( provider.symbol, provider.period, true // Ignore Ticks after Recieved a Signal Till new Candle ... ); // // Attach Event Listener ... if (mOnSignalConditions != NULL) { // // Attach Event Handlers ... provider.provider.AddOnSignalConditionEventHandler(mOnSignalConditions); } // // Set Signallers to Provider Class ... result = provider.provider.SetSignallers(provider.providers); if (!result) { return result; } // // Initialize Provider ... result = provider.provider.SetConfig(mProviderConfig); // // Add Prepared Provider to Providers ... Add( provider, mProviders); // return result; } // // Add Providers ... int AddProviders( X121SignalProvider &providers[] // Specific Providers ... ) { // int result = 0; // int providersCount = ArraySize(providers); if (providersCount <= 0) { return result; } // for (int i = 0; i < providersCount; i++) { // X121SignalProvider iProvider = providers[i]; // bool isAdded = AddProvider(iProvider); if (isAdded) { result++; } } // return result; } // // END Properties ... // // // START Overrides ... // // void OnPositionsChangedHandler(int count) { } // // Handle TakeProfit Event ... void OnTakeProfitTriggered(const XDeal &deal) { // // Since we Use Hedge in Min Profit ... // Some times a Position Modified and SL Trails ... // this Position closed through sl Event ... // here we Must Close positions's Pack Orders ... // // So We Have to Get Positions Pack ... XPositionPack dealPack; bool hasPack = mTrader.GetDealPack( deal, dealPack); if (hasPack) { HandleClosePack(dealPack); } // CancelAllEQMOrders(); } // // Handle StopLoss Event ... void OnStopLossTriggered(const XDeal &deal) { // // Since we Use Hedge in Min Profit ... // Some times a Position Modified and SL Trails ... // this Position closed through sl Event ... // here we Must Close positions's Pack Orders ... // // So We Have to Get Positions Pack ... XPositionPack dealPack; bool hasPack = mTrader.GetDealPack( deal, dealPack); if (hasPack) { HandleClosePack(dealPack); } // CancelAllEQMOrders(); } // // END Overrides ... // // // START Inheritance Functions ... // // void PrepareTag() { mTag = "X121EA:" + mSymbol + "," + ToString(mPeriod) + (string)mMagic; } // // Check Providers Guard States ... bool CheckGuard(XGuard &guards[]) { // bool result = false; // Clean(guards); // // Positions Management ... // HandlePositionManagement(); // int providersCount = ArraySize(mProviders); if (providersCount <= 0) { return result; } // for (int i = 0; i < providersCount; i++) { // X121SignalProvider iProvider = mProviders[i]; // XGuard iGuards[]; bool iHasGuard = iProvider.provider.GuardCheck(iGuards); if (iHasGuard) { // Copy( iGuards, guards, false); } } // // Here we Can Implement Custom Guards Senario ... // // Do Management Equity ... HandleEquityManagement(); // result = ArraySize(guards) > 0; // return result; } // // Check Providers for Signals ... bool SignalCheck(XSignal &signals[]) { // bool result = false; // Clean(signals); // // Since We may have Custom Supporting Senarios for Positions // if there is no Equity or Positions Count Passed ... // we Clear Account Policies Check here and do it after // recieveing Signals ... // // Check Providers Count ... int providersCount = ArraySize(mProviders); if (providersCount <= 0) { return result; } // // Loop through Providers to Recieve Market Sence based on each them ... for (int i = 0; i < providersCount; i++) { // // Get provider Descriptor Struct ... X121SignalProvider iProvider = mProviders[i]; // // Check Provider Pivot Point Ready ... int iFoundedPivots = iProvider.provider.CountPivots(); int iReuiredPivots = iProvider.provider.GetMinPivots(); if (iFoundedPivots < iReuiredPivots) { // // Start Retrieveing Pivot Points ... iProvider.provider.ProccessPivotPoints(); // // ignore Calculating Signals since Pivot Points recieved ... continue; } // // Retrieve Market Consitions from Specified Provider ... X121MarketConditions iConditions; bool iHasSignal = iProvider.provider.ProcessTick(iConditions); // // Check there is Signal or not ... if (iHasSignal && iConditions.hasSignal) { // // Check Signalling is Enabled by Signal type ... bool isiSignalLong = IsLong(iConditions.signal.type); if ((isiSignalLong && !mEnableLongs) || (!isiSignalLong && !mEnableShorts)) { continue; } // // Here we Calculate Signals tp/sl volume and etc based on given // configurations ... PrepareConditionsSignal(iConditions); // // Add Signal to Retrieved Signals Collection ... Add( iConditions.signal, signals); } } // // Here we proccess all Exists Registered Providers and get // probably signals and add them signals Array ... // // Check Signals Exists for Processing ... result = ArraySize(signals) > 0; // // IMPORTANT: // Since we have to Implement our Signal Execution Senario // Ignore this here for Default behaviour and implememt or Execution ... if (result) { // // Create an Array for Holding Allowed To Execute Signals ... // this filled by given Signals from all providers ... XSignal allowedSignals[]; // // Check Account has required Equity for open Trades or not ... bool hasEquity = CheckEquityForTrade(); if (hasEquity) { // // if Equity Exists ... // // Check Positions Count ... XPosition positions[]; int positionsCount = GetPositions(positions); // // Calculate Remained Positions based on configurations ... int remainedPositionsCount = mMaxAllowedPositions - positionsCount; // int incommingSignalsCount = ArraySize(signals); // // Check incomming signals and remained Positions count ... if (remainedPositionsCount >= incommingSignalsCount) { // // Since we have necessary Equity for Trade ... // and also remainedPositions count is bigger than incomming signals ... // Accept all incomming Signals ... Copy( signals, allowedSignals); } else { // // since we have necessary Equity for trade ... // but incomming Signals count is bigger than Max allowed positions at same time ... // we have to select only remains count ... for (int i = 0; i < remainedPositionsCount; i++) { // XSignal iSignal = signals[i]; // Add( iSignal, allowedSignals); } // int allowedSignalsCount = ArraySize(allowedSignals); if (allowedSignalsCount <= 0) { // // TODO: Implement Senario for when to Recieved Signals but // Max Allowed Trades Reached ... } } } else { // // there isn't enough Equity for Trade ... // How to Select Signals when there is no Equity for Trade ... // // TODO: we can Implement Equity Management here ... // LogMessage("No Equity ..."); } // // Check Allowed Signals Count ... int allowedSignalsCount = ArraySize(allowedSignals); if (allowedSignalsCount <= 0) { return false; } // // Now we Sure the Equity is OK and only have Acceptable Signals count ... // // Here We Have to Check Signals based On it's Providers ... allowedSignalsCount = CheckSignalsProviderState(allowedSignals); if (allowedSignalsCount <= 0) { return false; } // // Prepare Allowed Signals for Execution ... PrepareSignals(allowedSignals); // // Execute Signals oly when allowed ... int executed = mTrader.ExecuteSignals(allowedSignals); if (executed > 0) { // // Draw Signal ... // On Chart ... DrawSignals( allowedSignals, true); } // // Prevent Default Base Signal Execution ... // Clean(signals); // return false; } // return result; } // // END Inheritance Functions ... // // // START Provided Actions ... // // // END Provided Actions ... // // // Protected ... protected: // // Private ... private: // // Props ... X121SignalProvider mProviders[]; X121ProviderInputs mProviderConfig; TOnSignalConditions mOnSignalConditions; // // Actions ... // // Pepare a Collection Of Signals ... void PrepareSignals(XSignal &signals[]) { // int signalsCount = ArraySize(signals); if (signalsCount <= 0) { return; } // for (int i = 0; i < signalsCount; i++) { // PrepareSignal(signals[i]); } } // // EQUITYMANAGEMENT ... // // // All available Equity Actions Implemented here ... void HandleEquityManagement() { // // TODO: Complete this ... // // Here we Must first Check Number of Trades ... XPosition positions[]; int positionsCount = GetPositions(positions); if (positionsCount <= 0) { return; } // double profit = CalculatePositionsProfit(positions); double requiredProfit = CalculatePositionsProfit(positions); // if (profit > 0 && positionsCount >= mMaxAllowedPositions) { // // TODO: // Wait for Max Profit for Closing all Open Positions ... // Also Support Orders ... // // here we have to Multiply requirement profit for hedging ... bool canHedge = profit >= (requiredProfit * 1.5); string comment = "EQM Hedge ..."; int closed = mTrader.ClosePositions( positions, comment); if (closed > 0) { // // Cancel All Placed Support Orders ... CancelAllEQMOrders(); // string message = "EQM Closed (" + ToString(positionsCount) + ") due Hedge by: " + ToString(profit); // LogMessage(message); } // return; } else if (profit > 0 && positionsCount > 1) { // // Here we can Hedge Positions in regular Senario ... bool canHedge = profit >= requiredProfit; string comment = "EQM Hedge ..."; int closed = mTrader.ClosePositions( positions, comment); if (closed > 0) { // // Cancel All Placed Support Orders ... CancelAllEQMOrders(); // string message = "EQM Closed (" + ToString(positionsCount) + ") due Hedge by: " + ToString(profit); // LogMessage(message); } // return; } // // TODO: Add Longest Age in Props ... int longDetectionAgeForInDrawDownPositions = 26; int longDetectionAgeForUntriggeredSupports = 26; // // Here we have to Place Support Signals if there is no Equity ... bool hasEquity = CheckEquityForTrade(); if (profit < 0 && !hasEquity) { // // Retrieve and Placed EQM Support Orders ... HandleEQMSupportPlacement(); } else if (profit < 0 && hasEquity) { // // Here there are some Open Positions and we have eQuity but // there isn't new Signals and exists positions in DrawDown ... // // here we have to Generate EQM Support Signal ... // // First try to Find Max In Draw down Position ... XPosition inDPositions[]; int inDPositionsCount = GetInDrawdownPositions( inDPositions, NULL, NULL, NULL, NULL, X_POSITION_SELECT_MAX); if (inDPositionsCount <= 0) { return; } // XPosition maxInDPosition = inDPositions[0]; int maxInDPositionAge = GetAge(maxInDPosition); // bool isSupportable = maxInDPositionAge >= longDetectionAgeForInDrawDownPositions; if (!isSupportable) { return; } // // now we are sure Max In DrawDown Position is Supportable ... HandleEQMSupportPlacement(); } } // // Retrieve All EQM Placed Support Orders ... int GetEQMOrders( XOrder &orders[] // Hold Result ) { // int result = 0; // XOrder allOrders[]; int allOrdersCount = GetOrders(allOrders); if (allOrdersCount <= 0) { return result; } // // Extract EQM Orders ... result = GetEQMSupportOrders( orders, allOrders); // return result; } // // Retrieve All EQM Support Positions ... int GetEQMPositions( XPosition &positions[] // Hold Result ) { // int result = 0; // XPosition allPositions[]; int allPositionsCount = GetPositions(allPositions); if (allPositionsCount <= 0) { return result; } // // Extract EQM Positions ... result = GetEQMSupportPositions( positions, allPositions); // return result; } // // Cancel all EQM Placed Support Orders ... bool CancelAllEQMOrders() { // bool result = false; // XOrder eqmOrders[]; int eqmOrdersCount = GetEQMOrders(eqmOrders); if (eqmOrdersCount <= 0) { return result; } // result = mTrader.CancelOrders(eqmOrders); // return result; } // // Generate EQM Support Signals ... int GenerateEQMSupports( XSignal &supports[], // Holds Supports bool placeSL = true, // Place SL For EQM Supports bool placeTP = true // Place TP For EQM Supports ) { // int result = 0; // // Clean result Array ... Clean(supports); // // Since we Generate Support Signals based on Max In Drawdown Positions ... // we hae to Find it and then find it's Related Provider ... // then recieve Market Conditions based on it's Signaller's Provider ... // then try to Generate Supports ... XPosition inDrawdownPositions[]; int inDrawdownPositionsCount = GetInDrawdownPositions( inDrawdownPositions, NULL, // All Symbols ... NULL, // All TYpe Of Positions ... NULL, // All Periods ... NULL, // All Providers ... X_POSITION_SELECT_MAX // we need Max InDrawdown ... ); if (inDrawdownPositionsCount <= 0) { return result; } // // Since We Select Max here ... // and also check count ... // just Recieve Max In DD Position ... XPosition maxInDDPosition = inDrawdownPositions[0]; // // Here we can Select Provider based on InDD Position ... int providerIDX = GetProviderIndex( maxInDDPosition.symbol, maxInDDPosition.period); // // Validate Index ... if (providerIDX <= -1) { return result; } // double entry = GetEntry( maxInDDPosition.symbol, maxInDDPosition.type); // // Retrieve Market Conditions Based on Specific Provider ... X121MarketConditions conditions = mProviders[providerIDX] .provider .GetMarketConditions(0); // // Retrieve Support and Resistance ... XOHCLSupRes supRes = mProviders[providerIDX] .provider .GenerateSupportAndResistance( entry, 36 // ); // double volume = GetEQMSupportVolume(); // // Try to Find above peak and below vale Pivots ... double pivots[]; mProviders[providerIDX] .provider .FillPivotPoints(pivots); // // // GenerateFiboEQMSupports( // conditions, // maxInDDPosition, // supports, // pivots, // volume, // placeSL, // placeTP); // // GenerateSupportAndResistanceEQMSupports( // conditions, // maxInDDPosition, // supRes, // supports, // volume, // placeSL, // placeTP); // result = ArraySize(supports); // return result; } // // Count all open Positions Volume for supports ... double GetEQMSupportVolume( bool ignoreEQM = true // Ignore EQM Positions ) { // double result = 0; // // TODO: // add to Props ... double maxEQMSupportVolume = 0.3; // // Retrieve Positions ... XPosition positions[]; int positionsCount = GetPositions(positions); if (positionsCount <= 0) { return result; } // // Retrieve EQM Positions and Check ... // if it's count bigger than 0 means there are an Open // EQM Support Position and we do not have to do anything ... XPosition eqmPositions[]; int eqmPositionsCount = GetEQMPositions(eqmPositions); if (!ignoreEQM && eqmPositionsCount > 0) { return result; } // for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; // result += iPosition.volume; } // // Multiply Volume Summary ... // TODO: Make it Configurable ... result *= 1; if (result > maxEQMSupportVolume) { result = maxEQMSupportVolume; } // return result; } // void HandleEQMSupportPlacement() { // // TODO: Add Longest Age in Props ... int longDetectionAgeForInDrawDownPositions = 26; int longDetectionAgeForUntriggeredSupports = 26; // // Here we have to Place EQM Support Orders ... // // First Check Exists Supports ... XOrder orders[]; int ordersCount = GetEQMOrders(orders); if (ordersCount > 0) { // // When there are Exists Untriggered EQM Support Orders ... // first we have to check their Age ... // if it's longest as enough for replacing, cance all EQM Orders and regenerate new Ones ... // otherwise wait until they triggered or be long as enough ... // int minEQMSupportAge = 0; for (int i = 0; i < ordersCount; i++) { // XOrder iOrder = orders[i]; // int iAge = GetAge(iOrder); minEQMSupportAge = minEQMSupportAge == 0 || minEQMSupportAge > iAge ? iAge : minEQMSupportAge; } // // we have min support order's age ... // check it is long enough for cancelling or not ... bool isTooOld = minEQMSupportAge >= longDetectionAgeForUntriggeredSupports; if (!isTooOld) { return; } // // we are sre exists EQM Supports are To old ... bool isCancelled = CancelAllEQMOrders(); if (!isCancelled) { return; } } // XSignal signals[]; int signalsCount = GenerateEQMSupports(signals); if (signalsCount <= 0) { return; } // string comment = GenerateXEQMSupportComment(); int executed = mTrader.ExecuteSignals( signals, comment // ); if (executed > 0) { // string message = "Execute (" + ToString(executed) + ") EQM Supports ..."; // LogMessage(message); } } // // Check Signallers ... // when recieved signals we have to check each signal // based on it's signaller ... // if there isn't any open Position from it's signaller or // there was open positions and all of them in profit we accept new recieved signal ... // in this way we can handle balance between signallers and their positions and also // we prevent big losses ... int CheckSignalsProviderState(XSignal &signals[]) { // int result = 0; // int signalsCount = ArraySize(signals); if (signalsCount <= 0) { return result; } // XSignal tmp[]; Copy( signals, tmp); Clean(signals); // // Loop through Signals ... for (int i = 0; i < signalsCount; i++) { // XSignal iSignal = tmp[i]; // int providersCount = ArraySize(iSignal.providers); if (providersCount <= 0) { continue; } // string iSignaller = iSignal.providers[0]; // // Retrieve Signaller's Open Positions ... XPosition iSignallerPositions[]; int iSignallerPositionsCount = GetPositions( iSignallerPositions, iSignal.symbol, iSignal.type, iSignal.period, iSignaller); if (iSignallerPositionsCount <= 0) { // // this means we can accept Signal without Checking anything ... Add( iSignal, signals // ); // // TODO: Here we can Provide Support Signals for First Arrived Signal ... // continue; } // // here we have to check Signallers open Positions Profit ... double iSignallerPositionsProfit = CalculatePositionsProfit(iSignallerPositions); bool isInProfit = iSignallerPositionsProfit > mMinProfitPerTrade; if (!isInProfit) { continue; } // // this means all Signaller Open Positions in Profit ... // so we Accept Signal ... Add( iSignal, signals // ); } // Clean(tmp); // result = ArraySize(signals); // if (result > 0) { // // This means Signallers provide In Profits Positions Before ... // the Best thing is make them Risk Free at current Signals Minimum Entry ... // TODO: Complete This ... // for (int i = 0; i < result; i++) // { // // // XSignal iSignal = signals[i]; // // // HandleGuardHedgeAction( // iSignal.providers[0], // iSignal.symbol, // iSignal.type, // iSignal.period, // iSignal.entry // ); // } } // return result; } // // PROVIDERS ... // // // Find Specific Provider Index by using give symbol and period ... int GetProviderIndex( string symbol, // Trading Symbol ... ENUM_TIMEFRAMES period // Trading Time frame ... ) { // int result = -1; // // Validate Args ... if (period == NULL || symbol == NULL || StringLen(symbol) == 0) { return result; } // int providersCount = ArraySize(mProviders); if (providersCount <= 0) { return result; } // for (int i = 0; i < providersCount; i++) { // X121SignalProvider iProvider = mProviders[i]; // if (iProvider.symbol == symbol && iProvider.period == period) { // result = i; break; } } // return result; } // // Prepare Default Configurations for X121Provider Setup ... void PrepareProviderConfig() { // // Set Default X121 Provider Configurations ... // // XMAN ... // // Candle Timer ... mProviderConfig.xmanConfig.candleTimerColor = clrGold; mProviderConfig.xmanConfig.candleTimerCorner = CORNER_RIGHT_UPPER; // // Chart Style ... mProviderConfig.xmanConfig.upColor = clrLime; mProviderConfig.xmanConfig.downColor = clrRed; mProviderConfig.xmanConfig.lineColor = clrLime; mProviderConfig.xmanConfig.bearishColor = clrRed; mProviderConfig.xmanConfig.bullishColor = clrLime; mProviderConfig.xmanConfig.volumesColor = clrGreen; mProviderConfig.xmanConfig.chartMode = CHART_CANDLES; // // Market Cycles ... // // Level 1 ... mProviderConfig.xmanConfig.l1Method = X_PERIOD_AUTO; mProviderConfig.xmanConfig.l1Period = NULL; // // Level 1 ... mProviderConfig.xmanConfig.l2Method = X_PERIOD_AUTO; mProviderConfig.xmanConfig.l2Period = NULL; // // Level 1 ... mProviderConfig.xmanConfig.l3Method = X_PERIOD_AUTO; mProviderConfig.xmanConfig.l3Period = NULL; // // Level 1 ... mProviderConfig.xmanConfig.l4Method = X_PERIOD_AUTO; mProviderConfig.xmanConfig.l4Period = NULL; // // Fibonacci ... mProviderConfig.xmanConfig.fiboLevel1 = 0.236; mProviderConfig.xmanConfig.fiboLevel2 = 0.382; mProviderConfig.xmanConfig.fiboLevel3 = 0.5; mProviderConfig.xmanConfig.fiboLevel4 = 0.618; mProviderConfig.xmanConfig.fiboLevel5 = 0.764; // // Boundary Detection Modes ... mProviderConfig.xmanConfig.hhMode = MODE_HIGH; mProviderConfig.xmanConfig.llMode = MODE_LOW; // // Trend Detection ... mProviderConfig.xmanConfig.trendMultiplier = 3.5; mProviderConfig.xmanConfig.trendPriceAppliedTo = PRICE_MEDIAN; // // Ribbon Detection ... mProviderConfig.xmanConfig.ribbonMode = X_MA_SMMA; // // Hull Trend Detection ... mProviderConfig.xmanConfig.hullDivisor = 2.0; mProviderConfig.xmanConfig.hullUpAppliedTo = PRICE_HIGH; mProviderConfig.xmanConfig.hullDownAppliedTo = PRICE_LOW; // // SSL Channel ... mProviderConfig.xmanConfig.sslcMode = X_MA_SMA; mProviderConfig.xmanConfig.sslcUpAppliedTo = PRICE_HIGH; mProviderConfig.xmanConfig.sslcDownAppliedTo = PRICE_LOW; // // Presentation ... // NOTE: Since we Configure Presentation on PreDefine Section ... // here we turn of all Presentations as Default ... mProviderConfig.xmanConfig.showCandleTimer = false; mProviderConfig.xmanConfig.showCandles = false; mProviderConfig.xmanConfig.showHKCandles = false; mProviderConfig.xmanConfig.showSMHKCandles = false; mProviderConfig.xmanConfig.showPeaksAndVales = false; mProviderConfig.xmanConfig.showTrends = false; mProviderConfig.xmanConfig.fillTrends = false; mProviderConfig.xmanConfig.showLevels = false; mProviderConfig.xmanConfig.showConsolidations = false; mProviderConfig.xmanConfig.showRibbons = false; mProviderConfig.xmanConfig.showHull = false; mProviderConfig.xmanConfig.showSSLChannel = false; mProviderConfig.xmanConfig.showFibo1Levels = false; mProviderConfig.xmanConfig.showFibo2Levels = false; mProviderConfig.xmanConfig.showFibo3Levels = false; mProviderConfig.xmanConfig.showFibo4Levels = false; mProviderConfig.xmanConfig.showFibo5Levels = false; // PreDefineProviderConfig(); } // // Config Representation of X121 Provider Setup ... // for Specified Strategies ... void PreDefineProviderConfig() { // // Here we have to Name or Predefined Styles ... bool x786Config = true; // // by default we need to Show Candles and also Candle Timer ... mProviderConfig.xmanConfig.showCandles = true; mProviderConfig.xmanConfig.showCandleTimer = true; // // now we act based on Predefined Variables ... if (x786Config) { // bool showHK = false; bool showPVs = true; bool showFibo = true; bool showHull = true; bool showSSLC = true; bool showTrend = true; bool showRibbon = true; bool showPVLevels = false; bool showPVLevelConsolidations = false; // mProviderConfig.xmanConfig.showCandles = !showHK; mProviderConfig.xmanConfig.showHKCandles = showHK; mProviderConfig.xmanConfig.showSMHKCandles = true; // mProviderConfig.xmanConfig.showHull = showHull; mProviderConfig.xmanConfig.showTrends = showTrend; mProviderConfig.xmanConfig.showRibbons = showRibbon; mProviderConfig.xmanConfig.showSSLChannel = showSSLC; // mProviderConfig.xmanConfig.showFibo1Levels = showFibo; mProviderConfig.xmanConfig.showFibo2Levels = showFibo; mProviderConfig.xmanConfig.showFibo3Levels = showFibo; mProviderConfig.xmanConfig.showFibo4Levels = showFibo; mProviderConfig.xmanConfig.showFibo5Levels = showFibo; // mProviderConfig.xmanConfig.showPeaksAndVales = showPVs; // mProviderConfig.xmanConfig.showLevels = showPVLevels; mProviderConfig.xmanConfig.showConsolidations = showPVLevelConsolidations; } } // // Prepare Signal ... void PrepareConditionsSignal(X121MarketConditions &conditions) { // if (!conditions.hasSignal) { return; } // bool isLong = IsLong(conditions.signal.type); // // Check Calculate TP ... if ( conditions.signal.sl > 0 && conditions.signal.tp <= 0 && conditions.signal.r2r > 0 && conditions.signal.entry > 0) { // double riskPrice = MathAbs(conditions.signal.entry - conditions.signal.sl); double riskPoint = PriceToPoint( conditions.signal.symbol, riskPrice); double rewardPoint = riskPoint * conditions.signal.r2r; double rewardPrice = PointToPrice( conditions.signal.symbol, rewardPoint); // double tp = isLong ? conditions.signal.entry + rewardPrice : conditions.signal.entry - rewardPrice; // conditions.signal.tp = tp; } // PrepareSignal(conditions.signal); // conditions.signal.supportAndResistance = conditions.supportResistances; } // // TODO: Delete This ... void DrawConditionsSignalOnChart(X121MarketConditions &conditions) { // ulong mTicket = MathRand() * 100000; // DrawSignal( mTicket, conditions.signal); // DrawSupportResistance( 0, conditions.supportResistances, conditions.signal.providers[0]); } }; // // START Usefull Functions ... // // // END Usefull Functions ... //