/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Indicator // ------------------------------------------------- // Name: XCXCAEASignaller ... // Description: Class for XCAEA Signaller ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm Class for XCAEA Signaller" #property strict // // Imports ... #include "../../Classes/x-saherelm.base.class.mq5" #include "../../Classes/x-saherelm.x-cobject.class.mq5" #include "../Classes/xcaea.x-poi.detector.class.mq5" #include "../Classes/xcaea.x-poi.drawer.class.mq5" #include "../Helpers/xcaea.helper.mq5" #include "../Libraries/xcaea.signaller.lib.mq5" // // Definitions ... class XCXCAEASignaller : XCBase { // // Public ... public: // // Props ... bool useGuards; bool allowDraws; XCAEAInputs inputs; bool allowDrawPOIs; XBarTracker barTraker; XCXCAEAHelper *helper; int maxAllowedSetupAge; XBoxZone unavailables[]; XCXCAEAPOIDrawer *drawer; XCXCAEAHelper *analyseHelper; XCXCAEAPOIDetector *detector; XCAEAStrategyConditions mConditions; bool allowAnalyseDecisionZoneSignalling; bool allowTriggerBlockDecisionZoneSignalling; XCAEAStrategyConditions mConditionsCollection[]; // // Constructor ... XCXCAEASignaller( string _symbol, ENUM_TIMEFRAMES _period, ENUM_TIMEFRAMES _analysePeriod // ) { // symbol = _symbol; period = _period; analysePeriod = _analysePeriod; // Init(); } // // Deconstructor ... ~XCXCAEASignaller() { DeInit(); } // // Properties ... /** * Initialize ... */ void Init() { // // Configure Signaller Handler ... useGuards = false; allowDraws = true; allowDrawPOIs = false; maxAllowedSetupAge = 576; // // Signallings ... allowAnalyseDecisionZoneSignalling = false; allowTriggerBlockDecisionZoneSignalling = true; // // Initial Bar Tracker ... barTraker.Init( symbol, period // ); // // Initial Indicators ... InitHelper(); // // Initial POI Detector and Drawer ... InitDetectorAndDrawer(); // } /** * DeInitialize ... */ void DeInit() { // inputs.Clean(); // // Cleaning Draws ... drawer.Clear(); // ZeroMemory(drawer); ZeroMemory(helper); ZeroMemory(detector); ZeroMemory(analyseHelper); // Clean(unavailables); // mConditions.Clean(); Clean(mConditionsCollection); // mObjects.Clear(); mBarObjects.Clear(); // barTraker.Clean(); } // string GetSymbol() { return symbol; } // ENUM_TIMEFRAMES GetPeriod() { return period; } // // Signaller Tools ... /** * Detect Setup Conditions based on Signalling ... * * @param maxAllowedSLDistanceInPoint: int, Max Allowed SL Distance in Points (if Bigger thn Zero Provided) ... * * @return ( bool ) */ bool DetectSignalSetup( double tpReward = 3 // ) { // bool result = false; // // Normalize Args ... tpReward = NormalizeDouble(tpReward, 1); // // Check Bar Processing ... if (!barTraker.CanProcessBar()) { return result; } // int idx = -1; int count = 0; int zIndex = 0; bool has = false; int loopback = 10; int cIndex = zIndex + 1; bool isBullish = false; bool isBearish = false; // XOHCL zBar; result = zBar.Init( symbol, period, zIndex // ); if (!result) { // zBar.Clean(); // return result; } datetime cTime = zBar.time; // // Detect Pivots ... detector.Detect(zIndex); // // Validate Pivots ... detector.Validate( unavailables, zIndex // ); // // Draw Pivots ... if (allowDraws && allowDrawPOIs) { drawer.Draw(cTime); } // // Setup Conditions ... XBoxZone decisionZone; XCAEAConditions conditions; bool hasDecisionZone = false; ENUM_X_DIRECTION decisionZoneDir = X_DIRECTION_NONE; // // Check Decision Zone Detection Based On Several Signalling ... // // Analyse DecisionZone ... // In this Used Case we fond an Analyse TF OB // then waits for trigger on it ... if (allowAnalyseDecisionZoneSignalling) { // // Checking Signal's Decision Zone ... // On Analyse Time Frame ... hasDecisionZone = DetectDecisionZone( analyseHelper, drawer, decisionZone, decisionZoneDir, unavailables, conditions, zIndex, loopback // ); // // Here we Can Validate Decision Zone ... if (hasDecisionZone) { } } // // TriggerBlock Decision Zone ... // In this Used Case we found a Tigger Block and use it // for Triggering ... if (!hasDecisionZone && allowTriggerBlockDecisionZoneSignalling) { // int pushers = 0; // // We Can Detect Multiple Decision Zones ... XBoxZone tmpZone; XCAEATriggerBlockConfiguration config; // // Full Filteres ... config.ConfigureFullFilter(); bool hasFullFiltered = DetectTriggerBlock( tmpZone, conditions, helper, config, zIndex, loopback // ); if (hasFullFiltered) { // pushers++; // if (!decisionZone.IsValid()) { decisionZone = tmpZone; } } // tmpZone.Clean(); config.ConfigureSarRsiAdxFilter(); bool hasSarRsiAdxFiltered = DetectTriggerBlock( tmpZone, conditions, helper, config, zIndex, loopback // ); if (hasSarRsiAdxFiltered) { // pushers++; // if (!decisionZone.IsValid()) { decisionZone = tmpZone; } } // tmpZone.Clean(); config.ConfigureSarRsiTrendFilter(); bool hasSarRsiTrendFiltered = DetectTriggerBlock( tmpZone, conditions, helper, config, zIndex, loopback // ); if (hasSarRsiTrendFiltered) { // pushers++; // if (!decisionZone.IsValid()) { decisionZone = tmpZone; } } // tmpZone.Clean(); config.ConfigureSarAdxTrendFilter(); bool hasSarAdxTrendFiltered = DetectTriggerBlock( tmpZone, conditions, helper, config, zIndex, loopback // ); if (hasSarAdxTrendFiltered) { // pushers++; // if (!decisionZone.IsValid()) { decisionZone = tmpZone; } } // tmpZone.Clean(); config.ConfigureRsiAdxTrendFilter(); bool hasRsiAdxTrendFiltered = DetectTriggerBlock( tmpZone, conditions, helper, config, zIndex, loopback // ); if (hasRsiAdxTrendFiltered) { // pushers++; // if (!decisionZone.IsValid()) { decisionZone = tmpZone; } } // tmpZone.Clean(); config.ConfigureSarRsiFilter(); bool hasSarRsiFiltered = DetectTriggerBlock( tmpZone, conditions, helper, config, zIndex, loopback // ); if (hasSarRsiFiltered) { // pushers++; // if (!decisionZone.IsValid()) { decisionZone = tmpZone; } } // tmpZone.Clean(); config.ConfigureSarAdxFilter(); bool hasSarAdxFiltered = DetectTriggerBlock( tmpZone, conditions, helper, config, zIndex, loopback // ); if (hasSarAdxFiltered) { // pushers++; // if (!decisionZone.IsValid()) { decisionZone = tmpZone; } } // tmpZone.Clean(); config.ConfigureSarTrendFilter(); bool hasSarTrendFiltered = DetectTriggerBlock( tmpZone, conditions, helper, config, zIndex, loopback // ); if (hasSarTrendFiltered) { // pushers++; // if (!decisionZone.IsValid()) { decisionZone = tmpZone; } } // tmpZone.Clean(); config.ConfigureRsiAdxFilter(); bool hasRsiAdxFiltered = DetectTriggerBlock( tmpZone, conditions, helper, config, zIndex, loopback // ); if (hasRsiAdxFiltered) { // pushers++; // if (!decisionZone.IsValid()) { decisionZone = tmpZone; } } // tmpZone.Clean(); config.ConfigureRsiTrendFilter(); bool hasRsiTrendFiltered = DetectTriggerBlock( tmpZone, conditions, helper, config, zIndex, loopback // ); if (hasRsiTrendFiltered) { // pushers++; // if (!decisionZone.IsValid()) { decisionZone = tmpZone; } } // tmpZone.Clean(); config.ConfigureAdxTrendFilter(); bool hasAdxTrendFiltered = DetectTriggerBlock( tmpZone, conditions, helper, config, zIndex, loopback // ); if (hasAdxTrendFiltered) { // pushers++; // if (!decisionZone.IsValid()) { decisionZone = tmpZone; } } // hasDecisionZone = hasSarRsiFiltered || hasSarAdxFiltered || hasRsiAdxFiltered || hasSarTrendFiltered || hasRsiTrendFiltered || hasAdxTrendFiltered || hasSarRsiAdxFiltered || hasSarRsiTrendFiltered || hasSarAdxTrendFiltered || hasRsiAdxTrendFiltered; // if (hasDecisionZone) { // drawer.DrawBox( decisionZone, cTime, false, // Draw Middle ... true // Ignore Type ... ); // Print(ToString(decisionZone.dir) + " Trigger Block Detected (" + ToString(pushers) + ") ..."); } // tmpZone.Clean(); } // // Make Signal Box UnAvailable ... if (hasDecisionZone) { // decisionZoneDir = decisionZone.dir; // AddRef( decisionZone, unavailables // ); } // isBullish = hasDecisionZone && IsBullish(decisionZoneDir); // isBearish = hasDecisionZone && IsBearish(decisionZoneDir); // result = isBullish || isBearish; if (result) { // // Do What we Want ... barTraker.Waits(); // double pivot = isBullish ? decisionZone.lower : decisionZone.upper; // double point = isBullish ? decisionZone.upper : decisionZone.lower; // // Prepare Conditions ... mConditions.point = point; mConditions.pivot = pivot; mConditions.symbol = symbol; mConditions.period = period; mConditions.time = zBar.time; mConditions.reward = tpReward; mConditions.provider = "XCAEA"; mConditions.setupTime = zBar.time; mConditions.dir = decisionZoneDir; mConditions.conditions = conditions; mConditions.decisionZone = decisionZone; } // // Cleanup Resource ... // zBar.Clean(); conditions.Clean(); decisionZone.Clean(); // return result; } /** * Detect Trigger Conditions for Specified Signal ... * * @param conditions: XCAEAStrategyConditions instance Reference, Specified Signal Conditions ... * @param maxAllowedSetupAge: specified Setup Age for Expiration (if bigger than Zero) ... * * @return ( bool ) */ bool DetectSignalTrigger( XCAEAStrategyConditions &conditions, int barIndex = 0 // ) { // bool result = false; // // Normalize Args ... barIndex = NormalizeInt(barIndex, 0); // // Validate Setup ... result = conditions.IsSetuped(); if (!result) { return result; } // // Reading Requirements ... // int loopback = 10; double ask = GetAsk(symbol); double bid = GetBid(symbol); datetime cTime = TimeCurrent(); double points = GetPoints(symbol); datetime setupTime = conditions.setupTime; ENUM_X_DIRECTION setupDir = conditions.dir; // bool isBullish = IsBullish(setupDir); bool isBearish = IsBearish(setupDir); // // Extract Current Bar Conditions ... helper.GetConditions( conditions.conditions, barIndex, loopback // ); // // Check Signal Validation ... // IMPORTANT: since all Validations done in SetUp Process ... // here we only Execute Signal ... // result = isBullish || isBearish; if (!result) { return result; } // bool has = false; int zIndex = 0; int cIndex = zIndex + 1; int pIndex = cIndex + 1; int p2Index = pIndex + 1; // // Checking Trigger Conditions ... double sl = 0; double tp = 0; XTarget targets[]; ENUM_X_DIRECTION triggerDir = X_DIRECTION_NONE; int toIDX = conditions.decisionZone.ToIndex(); int fromIDX = conditions.decisionZone.FromIndex(); // bool isAnalyseSignalled = conditions.decisionZone.period == analyseHelper.GetPeriod(); // ENUM_XCAEA_TIGGER_TYPE decisionZoneType = GetType(conditions.decisionZone.type); bool isTriggerBlockSignalled = IsValid(decisionZoneType); // // Looking for Analyse Helper Triggers ... if (isAnalyseSignalled && allowAnalyseDecisionZoneSignalling) { // // Trigger Analyse Signal ... // // Check Box Size ... double maxAllowedBoxRange = 400; double range = conditions.decisionZone.GetRange(); bool isTooLarge = range > (maxAllowedBoxRange * points); double decisionMiddlePrice = conditions.decisionZone.GetMid(); // // Detect Required Pivots ... XBoxZone decisionPivots[]; ENUM_XCA_PIVOTS allowedTypes[]; if (isBullish) { // Add( XCA_OB_BULL, allowedTypes // ); } else { // Add( XCA_OB_BEAR, allowedTypes // ); } Add( XCA_PEAK, allowedTypes // ); Add( XCA_VALE, allowedTypes // ); int decisionPivotsCount = detector.FillPivots( conditions.decisionZone, decisionPivots, unavailables, allowedTypes, cTime // ); // // Draw Pivots of Decision Zone only when // it's Too Large ... if (false && allowDraws && isTooLarge && HasChild(decisionPivots)) { // for (int i = 0; i < decisionPivotsCount; i++) { // drawer.DrawBox( decisionPivots[i], cTime, false, // Draw Middle ... true // Ignore Type ... ); } } // // Define a Temparory Objects // Array instance for Holding Drawn Objects ... CArrayObj *iObjects; iObjects = new CArrayObj(); // // Check Different Trigger Conditions ... // // Checking Trigger Cond 0 ... bool canTriggerCond0 = false; // // Checking Trigger Cond 1 ... bool canTriggerCond1 = false; if (isTooLarge) { // canTriggerCond1 = CanTriggerCond1( helper, conditions.decisionZone, decisionPivots, triggerDir, sl, targets, allowDraws, iObjects, barIndex // ); } // // Checking Trigger Cond 2 ... bool canTriggerCond2 = false; if (!isTooLarge) { // canTriggerCond2 = CanTriggerCond2( helper, conditions.decisionZone, decisionPivots, triggerDir, sl, targets, allowDraws, iObjects, barIndex // ); } // // Checking Trigger Cond 3 ... bool canTriggerCond3 = false; // // Adding Drawn Objects to Drawn Stores ... for (int i = 0; i < iObjects.Total(); i++) { mObjects.Add(iObjects.At(i)); } // // Summarizing Result ... result = canTriggerCond0 || canTriggerCond1 || canTriggerCond2 || canTriggerCond3; } else if (isTriggerBlockSignalled && allowTriggerBlockDecisionZoneSignalling) { // // Trigger TRIGGER Block Signal ... // // since we have to Trigger all TRIGGER Block's Signals // exactly on Setting ups ... result = isBullish || isBearish; if (result) { // triggerDir = isBullish ? X_DIRECTION_BULLISH : X_DIRECTION_BEARISH; // sl = isBullish ? conditions.decisionZone.lower : conditions.decisionZone.upper; // conditions.reward = 2; } } // isBullish = result && IsBullish(triggerDir); isBearish = result && IsBearish(triggerDir); // // Configure Conditions for Preparing Signal ... if (result) { // // Draw Decision Zone ... if (allowDraws) { // drawer.DrawBox( conditions.decisionZone, cTime, true, // Draw Middle Line ... true // Ignore Type ... ); } // // Reconfigure Position TP/SL Entry and etc ... // double entry = GetEntry( conditions.symbol, triggerDir // ); conditions.entry = entry; // double spred = GetSpread(conditions.symbol); // double risk = MathAbs(entry - sl) + spred; double reward = (risk * conditions.reward); tp = isBullish ? entry + reward : entry - reward; // conditions.sl = sl; conditions.tp = tp; conditions.dir = triggerDir; conditions.triggerTime = cTime; conditions.type = isBullish ? X_POSITION_TYPE_LONG : X_POSITION_TYPE_SHORT; // // Preparing Targets ... XTarget iTarget; double iPrice = 0; double iReward = 0; // // Partial Close 25% of Volume in R2R 1 ... iReward = risk * 1; iPrice = isBullish ? entry + iReward : entry - iReward; iPrice = NormalizePrice(iPrice, conditions.symbol); iTarget.target = iPrice; iTarget.volumeMultiplier = 0.25; AddRef( iTarget, targets // ); // // Partial Close 25% of Volume in R2R 2 ... iReward = risk * 1.90; iPrice = isBullish ? entry + iReward : entry - iReward; iPrice = NormalizePrice(iPrice, conditions.symbol); iTarget.target = iPrice; iTarget.volumeMultiplier = 0.25; AddRef( iTarget, targets // ); // // Risk Free in R2R 3 ... iReward = risk * 2.90; iPrice = isBullish ? entry + iReward : entry - iReward; iPrice = NormalizePrice(iPrice, conditions.symbol); // iTarget.doRF = true; iTarget.volumeMultiplier = 0.25; iTarget.target = iPrice; AddRef( iTarget, targets // ); // // Handling Targets ... bool hasTargets = HasChild(targets); if (hasTargets) { // Copy( targets, conditions.targets // ); } // } // // Validating Conditions if not Triggered ... if (!result) { // // Check Box Age ... int age = conditions.GetSetupAge(); bool has = age <= maxAllowedSetupAge; if (!has) { conditions.Clean(); } // // Checking Decision Zone Validation ... bool isValid = conditions.decisionZone.IsValid(); if (!isValid) { conditions.Clean(); } // // Check Box Price ... has = IsBoxBreaked( helper, conditions.decisionZone, barIndex // ); if (has) { conditions.Clean(); } } // // Cleanup ... // return result; } /** * Detect Guards bsed on Signalling Class ... * * @param guards: XCAEAGuard instance Collection, Holds Provided Guards ... * @param positions: XPosition instance Collection, Provides Signalling Based Positions for Apply Guards on them ... * @param provider: X121SMCStrategySignalProviderData instance Reference, Specified Data for Cycles ... * * @return ( bool ) */ bool DetectGuards( XCAEAGuard &guards[], const XPosition &positions[] // ) { // bool result = false; // // TODO: Implement this ... // return result; } /** * Add Conditions to Conditions Collection if not Exists ... * * @param maxAllowed: int, Specified Max Allowed Holding Conditions ... * * @return ( int ) */ int AddConditionsIfNotExists( int maxAllowed = 10 // ) { // int result = 0; // bool isSetuped = IsValid(mConditions.setupTime) && HasDirection(mConditions.dir); if (!isSetuped) { return result; } // int count = ArraySize(mConditionsCollection); if (IsValidSize(count)) { // // Copy Original Items ... XCAEAStrategyConditions tmpItems[]; Copy( mConditionsCollection, tmpItems // ); // // Prese Item Data ... bool isBullish = IsBullish(mConditions.dir); // for (int i = 0; i < count; i++) { // XCAEAStrategyConditions iItem = tmpItems[i]; // bool canRemove = mConditions.dir == iItem.dir && mConditions.pivot == iItem.pivot; if (canRemove) { // ArrayRemove( mConditionsCollection, i, 1 // ); } } // Clean(tmpItems); } // AddRef( mConditions, mConditionsCollection // ); // // Remove Olds ... CleanupArray( mConditionsCollection, maxAllowed // ); // result = ArraySize(mConditionsCollection); // return result; } // // Protected ... protected: // // // Private ... private: // // Props ... string symbol; ENUM_TIMEFRAMES period; ENUM_TIMEFRAMES analysePeriod; // CArrayObj mObjects; CArrayObj mBarObjects; // void InitHelper() { // inputs.Default(); // // Configure Indicators ... // // XCC ... inputs.ccInputs.showCandles = true; // // XCT ... inputs.ctInputs.showCandleTime = true; // // X3MA ... // inputs.x3maInputs.applyColor = true; // inputs.x3maInputs.fastLength = 5; // inputs.x3maInputs.showFast = true; inputs.x3maInputs.showSlow = false; inputs.x3maInputs.showMedium = false; // // XCA ... // // inputs.caInputs.sarStep = 0.001; // inputs.caInputs.sarMax = 0.05; // inputs.caInputs.supResSmoothingLength = 7; inputs.caInputs.supResSmoothingMode = X_MA_MODE_NONE; // inputs.caInputs.showKI = false; inputs.caInputs.showTKI = false; inputs.caInputs.showMAH = false; inputs.caInputs.showMAL = false; inputs.caInputs.showMAC = false; inputs.caInputs.showSar = true; inputs.caInputs.showVidya = false; inputs.caInputs.showTrend = true; inputs.caInputs.showSwings = true; inputs.caInputs.showFiboLevel1 = false; inputs.caInputs.showFiboLevel2 = false; inputs.caInputs.showFiboLevel3 = false; inputs.caInputs.showFiboLevel4 = false; inputs.caInputs.showFiboLevel5 = false; inputs.caInputs.showPeaksAndVales = true; inputs.caInputs.showPeakAndValeGolden = false; inputs.caInputs.showSupportAndResistance = false; // // XOSCS ... // inputs.oscsInputs.rsiLength = 5; // inputs.oscsInputs.rsiOBLevel = 90; // inputs.oscsInputs.rsiOSLevel = 10; // inputs.oscsInputs.cciLength = 7; // inputs.oscsInputs.cciOBLevel = 130; // inputs.oscsInputs.cciOSLevel = -130; // inputs.oscsInputs.mfiLength = 5; // inputs.oscsInputs.rviLength = 5; // // Oscillators Views ... inputs.showRSI = false; inputs.showCCI = false; inputs.showMFI = false; inputs.showRVI = false; inputs.showADX = false; inputs.showMACD = false; // // // // // XCAEA Helper ... helper = new XCXCAEAHelper(); helper.Init( symbol, period, inputs // ); // // XCAEA Analyse Helper ... analyseHelper = new XCXCAEAHelper(); analyseHelper.Init( symbol, analysePeriod, inputs // ); } // void InitDetectorAndDrawer() { // // Initialize and Configure Detector ... detector = new XCXCAEAPOIDetector(helper); // // Common Configurations ... detector.maxAllowedPivots = 0; detector.pivotVerifications = 5; detector.ticksDividerInPoints = 15; detector.pivotDetectionLoopbac = 200; // // Configure Detector ... // // SWING ... // detector.maxAllowedSwingLifetime = 0; // detector.detectSWLPivots = false; detector.detectSWHPivots = false; // // PV ... // detector.maxAllowedPVLifetime = 0; detector.applySwingsOnPVPivots = false; detector.selectRejectedPVPivots = false; detector.selectEngulfedPVPivots = false; detector.applySupportAndResistanceOnPVPivots = false; // detector.detectPeakPivots = true; detector.detectValePivots = true; // // OB ... detector.maxAllowedOBLifetime = 0; // detector.detectOBBullishPivots = true; detector.detectOBBearishPivots = true; // // FVG ... // detector.selectSameBarFVGs = false; detector.maxAllowedFVGLifetime = 0; detector.validateFVGUsingPV = false; detector.applyPVToFVGBoundary = false; detector.selectRejectedFVGPivots = false; detector.selectEngulfedFVGPivots = false; detector.validateFVGUsingManalyser = false; detector.applyLastBarToFVGBoundary = false; detector.selectOnlyFVGWhichHasIndirectionalLastBar = false; // detector.detectFVGBullishPivots = false; detector.detectFVGBearishPivots = false; // // TREND ... // detector.maxAllowedTrendLifetime = 0; detector.detectTrendBullishPivots = false; detector.detectTrendBearishPivots = false; // // DRAWER ... // // Initialize and Configure Drawer ... drawer = new XCXCAEAPOIDrawer(detector); // drawer.ignoreUpdateOSCTos = true; // // Configure Drawer ... drawer.drawSWHPivots = false; drawer.drawSWLPivots = false; drawer.drawPeakPivots = true; drawer.drawValePivots = true; drawer.drawOBBullishPivots = false; drawer.drawOBBearishPivots = false; drawer.drawFVGBullishPivots = false; drawer.drawFVGBearishPivots = false; drawer.drawTrendBullishPivots = false; drawer.drawTrendBearishPivots = false; // // Configure Styles ... // // SWING ... // // SWH ... XCAPivotStyle swhStyle; swhStyle.width = 2; swhStyle.clr = clrMagenta; swhStyle.style = STYLE_SOLID; drawer.swhPivotStyle = swhStyle; swhStyle.Clean(); // // SWL ... XCAPivotStyle swlStyle; swlStyle.width = 2; swlStyle.clr = clrAqua; swlStyle.style = STYLE_SOLID; drawer.swlPivotStyle = swlStyle; swlStyle.Clean(); // // PV ... // // PEAK ... XCAPivotStyle peakStyle; peakStyle.width = 2; peakStyle.clr = clrMagenta; peakStyle.style = STYLE_SOLID; drawer.peakPivotStyle = peakStyle; peakStyle.Clean(); // // VALE ... XCAPivotStyle valeStyle; valeStyle.width = 2; valeStyle.clr = clrAqua; valeStyle.style = STYLE_SOLID; drawer.valePivotStyle = valeStyle; valeStyle.Clean(); // // OB ... // // Bullish ... XCAPivotStyle obBullishStyle; obBullishStyle.width = 2; obBullishStyle.clr = clrLime; obBullishStyle.style = STYLE_DASH; drawer.obBullishPivotStyle = obBullishStyle; obBullishStyle.Clean(); // // Bearish ... XCAPivotStyle obBearishStyle; obBearishStyle.width = 2; obBearishStyle.clr = clrRed; obBearishStyle.style = STYLE_DASH; drawer.obBearishPivotStyle = obBearishStyle; obBearishStyle.Clean(); // // FVG ... // // Bullish ... XCAPivotStyle fvgBullishStyle; fvgBullishStyle.width = 2; fvgBullishStyle.clr = clrLime; fvgBullishStyle.style = STYLE_DASH; drawer.fvgBullishPivotStyle = fvgBullishStyle; fvgBullishStyle.Clean(); // // Bearish ... XCAPivotStyle fvgBearishStyle; fvgBearishStyle.width = 2; fvgBearishStyle.clr = clrRed; fvgBearishStyle.style = STYLE_DASH; drawer.fvgBearishPivotStyle = fvgBearishStyle; fvgBearishStyle.Clean(); // // TREND ... // // Bullish ... XCAPivotStyle trendBullishStyle; trendBullishStyle.width = 2; trendBullishStyle.clr = clrLime; trendBullishStyle.style = STYLE_DOT; drawer.trendBullishPivotStyle = trendBullishStyle; trendBullishStyle.Clean(); // // Bearish ... XCAPivotStyle trendBearishStyle; trendBearishStyle.width = 2; trendBearishStyle.clr = clrRed; trendBearishStyle.style = STYLE_DOT; drawer.trendBearishPivotStyle = trendBearishStyle; trendBearishStyle.Clean(); } // }; //