// struct XPivot { // double pivot; // Pivot Price ... int breaks; // Number of Breaks ... int rejects; // Number of Rejects ... // void XPivot() { Clean(); } // // Tools ... // // Cleanup ... void Clean() { // pivot = 0; breaks = 0; rejects = 0; } // // Validate ... bool IsValid() { // bool result = false; // result = pivot > 0; // return result; } }; // struct XPivotTracker { // XPivot pivots[]; // // Constructor ... void XPivotTracker() { Clean(); } // // Tools ... // // Cleanup ... void Clean() { // Clean(pivots); } // int Count() { return ArraySize(pivots); } // double Get(int index) { // double result = 0; // NormalizeIndex(index, pivots); // XPivot iPivot = pivots[index]; // result = iPivot.pivot; // return result; } // XPivot GetPivot(int index) { // XPivot result; // NormalizeIndex(index, pivots); // result = pivots[index]; // return result; } // bool Add(double mPivot) { // bool result = false; // result = mPivot > 0 && !Has(mPivot); if (!result) { return result; } // XPivot pivot; pivot.pivot = mPivot; // AddRef( pivot, pivots // ); // result = true; // return result; } // int Adds(double &mPivots[]) { // int result = 0; // int pivotsCount = ArraySize(mPivots); if (!IsValidSize(pivotsCount)) { return result; } // for (int i = 0; i < pivotsCount; i++) { // double iPivot = mPivots[i]; // bool isAdded = Add(iPivot); if (isAdded) { result++; } } // return result; } // int FindIndex(double mPivot) { // int result = -1; // if (mPivot <= 0) { return result; } // int count = Count(); if (!IsValidSize(count)) { return result; } // for (int i = 0; i < count; i++) { // XPivot iPivot = pivots[i]; // if (iPivot.pivot == mPivot) { // result = i; break; } } // return result; } // double Has(double mPivot) { // bool result = false; // int pivotIDX = FindIndex(mPivot); result = pivotIDX >= 0; // return result; } // int Reject(double mPivot) { // int result = 0; // int pivotIDX = FindIndex(mPivot); if (pivotIDX < 0) { return result; } // pivots[pivotIDX].rejects++; // result = pivots[pivotIDX].rejects; // return result; } // int Break(double mPivot) { // int result = 0; // int pivotIDX = FindIndex(mPivot); if (pivotIDX < 0) { return result; } // pivots[pivotIDX].breaks++; // result = pivots[pivotIDX].breaks; // return result; } // bool Remove(double mPivot) { // bool result = false; // int pivotIDX = FindIndex(mPivot); result = pivotIDX >= 0; if (!result) { return result; } // result = ArrayRemove( pivots, pivotIDX, 1 // ); // return result; } // bool HasChild() { // bool result = false; // int count = Count(); result = IsValidSize(count); // return result; } }; // // Model Support and Resistance // for Specific Bar ... struct XOHCLSupRes { // // Props ... // /// Resistances ... double res[]; // // Supports ... double sup[]; // // Constructor ... XOHCLSupRes() { Clean(); } // // Init ... bool Init( double price, // Price ... const double &pivots[], // Provided Pivot Points ... int count = 3, // Number of Requireds ... double step = 0 // Distance between each item with it's Last Side ... ) { // bool result = false; // Clean(); // if (price <= 0) { return result; } // int pivotsCount = ArraySize(pivots); if (pivotsCount <= 0) { return result; } // if (count <= 0 || count > pivotsCount - 1) { return result; } // double lastR = 0; double tmpR[]; // double lastS = 0; double tmpS[]; // // Extract Supports ... // which prices is under low of candle ... // // Extract Resistance ... // which prices is over high of candle ... for (int i = 0; i < pivotsCount; i++) { // double iFlat = pivots[i]; // if (iFlat > price) { // bool canAdd = step <= 0 ? true : lastR == 0 || MathAbs(iFlat - lastR) >= step; if (canAdd) { // Add( iFlat, tmpR); // lastR = iFlat; } } else if (iFlat < price) { // bool canAdd = step <= 0 ? true : lastS == 0 || MathAbs(iFlat - lastS) >= step; if (canAdd) { // Add( iFlat, tmpS); // lastS = iFlat; } } } // // Sorting Founded Resistance and Supports ... // // Since Resistance Levels must be Increasing ... ArraySort(tmpR); // // Since Support Levels must be Decreasing ... ArraySort(tmpS); ArrayReverse(tmpS); // // Fill Resistance ... int tmpRCount = ArraySize(tmpR); if (tmpRCount > 0) { // if (tmpRCount < count) { // ArrayCopy( res, tmpR); } else { // ArrayCopy( res, tmpR, 0, 0, count); } } // // Fill Supports ... int tmpSCount = ArraySize(tmpS); if (tmpSCount > 0) { // if (tmpSCount < count) { // ArrayCopy( sup, tmpS); } else { // ArrayCopy( sup, tmpS, 0, 0, count); } } // result = IsValid(); // return result; } // // Tools ... // // Cleanup ... void Clean() { // Clean(sup); Clean(res); } // // Validate ... bool IsValid() { // bool result = false; // result = // CountSupports() > 0 || CountResistances() > 0 // ; // return result; } // int CountSupports() { return ArraySize(sup); } // int CountResistances() { return ArraySize(res); } }; // // Track Value Changes ... template struct XValueTracker { // // Definitions ... // // Model a Value Change ... struct XValueChange { // // Props ... datetime at; // Change Time T from; // Before Change Value T to; // After Change Value // // Constructor ... XValueChange() { Clean(); } // // Cleanup ... void Clean() { // at = NULL; from = NULL; to = NULL; } // // Validate ... bool IsValid() { // bool result = false; // result = IsValid(at); if (!result) { return result; } // result = NotEmpty(from) && NotEmpty(to); // return result; } }; // // Props ... XValueChange changes[]; // Hold Changes // // Constructor ... XValueTracker() { Clean(); } // // Track a Change Happens Or Not ... bool Track( const T &source[] // Data Source for Track Changes ) { // bool result = false; // if (ArraySize(source) <= 1) { return result; } // datetime time = TimeCurrent(); // double from = source[1]; double to = source[0]; // result = to != from; if (result) { return result; } // XValueChange lastChange; bool hasLastChange = GetLastItem( lastChange, changes // ); result = !hasLastChange ? true : lastChange.at < time && lastChange.to != to && lastChange.from != from; if (!result) { return result; } // lastChange.Clean(); // lastChange.to = to; lastChange.at = time; lastChange.from = from; // AddRef( lastChange, changes // ); // return result; } // // Tools ... // // Cleanup ... void Clean() { Clean(changes); } }; // int GenerateEQMOrders( XSignal &orders[], // Result XPosition &position, // Supported Position XOHCLSupRes &supRes, // Data Source bool longs = true, bool shorts = true // ) { // int result = 0; // Clean(orders); // if (!supRes.IsValid() || !position.IsValid()) { return result; } // if (longs) { // double longLevels[]; // Copy( supRes.res, longLevels // ); // double minSup = GetMin( supRes.sup // ); if (minSup > 0) { // Add( minSup, longLevels // ); } // ArraySort(longLevels); // if (ArraySize(longLevels) > 2) { // for (int i = 0; i < ArraySize(longLevels) - 2; i++) { // double iSL = longLevels[i]; double iEntry = longLevels[i + 1]; double iTP = longLevels[i + 2]; // XSignal iSignal; bool isPrepared = iSignal.PrepareStopLong( position.symbol, XEQMSupportToken, position.period, iEntry, position.volume, iSL, iTP // ); if (isPrepared) { // string comment = GenerateSupportTag(position.ticket); iSignal.comment = comment; // AddRef( iSignal, orders // ); } } } } // if (shorts) { // double shortLevels[]; // Copy( supRes.sup, shortLevels // ); // double maxRes = GetMax( supRes.res // ); if (maxRes > 0) { // Add( maxRes, shortLevels // ); } // ArraySort(shortLevels); ArrayReverse(shortLevels); // if (ArraySize(shortLevels) > 2) { // for (int i = 0; i < ArraySize(shortLevels) - 2; i++) { // double iSL = shortLevels[i]; double iEntry = shortLevels[i + 1]; double iTP = shortLevels[i + 2]; // XSignal iSignal; bool isPrepared = iSignal.PrepareStopShort( position.symbol, XEQMSupportToken, position.period, iEntry, position.volume, iSL, iTP // ); if (isPrepared) { // string comment = GenerateSupportTag(position.ticket); iSignal.comment = comment; // AddRef( iSignal, orders // ); } } } } // result = ArraySize(orders); // return result; }