//+--------------------------------------------------------------------+ //| Copyright: (C) 2016 Forex Software Ltd. | //| Website: http://forexsb.com/ | //| Support: http://forexsb.com/forum/ | //| License: Proprietary under the following circumstances: | //| | //| This code is a part of Forex Strategy Builder. It is free for | //| use as an integral part of Forex Strategy Builder. | //| One can modify it in order to improve the code or to fit it for | //| personal use. This code or any part of it cannot be used in | //| other applications without a permission. | //| The contact information cannot be changed. | //| | //| NO LIABILITY FOR CONSEQUENTIAL DAMAGES | //| | //| In no event shall the author be liable for any damages whatsoever | //| (including, without limitation, incidental, direct, indirect and | //| consequential damages, damages for loss of business profits, | //| business interruption, loss of business information, or other | //| pecuniary loss) arising out of the use or inability to use this | //| product, even if advised of the possibility of such damages. | //+--------------------------------------------------------------------+ #property copyright "Copyright (C) 2016 Forex Software Ltd." #property link "http://forexsb.com" #property version "2.1" #property strict #include #include //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class RegressionPolynomial : public Indicator { public: RegressionPolynomial(SlotTypes slotType) { SlotType=slotType; IndicatorName="RegressionPolynomial"; WarningMessage = ""; IsAllowLTF = true; ExecTime = ExecutionTime_DuringTheBar; IsSeparateChart = true; IsDiscreteValues = false; IsDefaultGroupAll = false; } virtual void Calculate(DataSet &dataSet); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void RegressionPolynomial::Calculate(DataSet &dataSet) { Data=GetPointer(dataSet); BasePrice basePrice = (BasePrice)ListParam[2].Index; int period = (int)NumParam[0].Value; int degree = (int)NumParam[3].Value; int signal = (int)NumParam[2].Value; double dLevel = 0; MAMethod maMethod = (MAMethod )ListParam[3].Index; int iPrvs = CheckParam[0].Checked ? 1 : 0; int iFirstBar = MathMax(period,signal) + 2 + degree*2; double adBasePrice[]; Price(basePrice,adBasePrice); double Line[]; ArrayResize(Line,Data.Bars); ArrayInitialize(Line,0); double adMA1[]; MovingAverage(period, 0, MAMethod_Weighted, adBasePrice,adMA1); double adMA2[]; MovingAverage(period, 0, MAMethod_Simple, adBasePrice,adMA2); for (int iBar = iFirstBar; iBar < Data.Bars; iBar++) { double a[10,10]; double b[10]; double x[10]; double sx[20]; if(degree == 1) { Line[iBar] = (3 * adMA1[iBar] - 2 * adMA2[iBar]); } else if(degree == 2) { int i = 1; double sum = 0; for (int j = 0; j < period; j++, i++) { sum += adBasePrice[iBar-j] * MathPow(period - i + 1, 2); } double value = 6.0 / (period * ( period + 1) * (2 * period + 1)) ; double qwma = (value * sum); Line[iBar] = 3.0 * adMA2[iBar] + qwma * (10 - 15 / (period + 2 )) - adMA1[iBar] * (12 - 15 / (period + 2)); } else { int k; double t; int degree1; sx[1] = period + 1; degree1 = degree + 1; for(int i = 1; i <= degree1 * 2 - 2; i++) { sx[i+1] = 0; for(int n = 0; n <= period; n++) { sx[i+1] += MathPow(n, i); } } for(int i = 1; i <= degree1; i++) { b[i] = 0; for(int n = 0; n <= period; n++) { if(i == 1) { b[i] += adBasePrice[iBar-n]; } else { b[i] += adBasePrice[iBar-n] * MathPow(n, i - 1); } } } for(int j = 1; j <= degree1; j++) { for(int i = 1; i <= degree1; i++) { k = i + j - 1; a[i, j] = sx[k]; } } for(k = 1; k <= degree1-1; k++) { int l = 0; double mm = 0; for(int i = k; i <= degree1; i++) { if(MathAbs(a[i, k]) > mm) { mm = MathAbs(a[i, k]); l = i; } } if (l != k) { for(int j = 1; j <= degree1; j++) { t = a[k, j]; a[k, j] = a[l, j]; a[l, j] = t; } t = b[k]; b[k] = b[l]; b[l] = t; } double div = 0; for(int i = k + 1; i <= degree1; i++) { div = a[i, k] / a[k, k]; for(int j = 1; j <= degree1; j++) { if(j == k) { a[i, j] = 0; } else { a[i, j] = a[i, j] - div * a[k, j]; } } b[i] = b[i] - div * b[k]; } } x[degree1] = b[degree1] / a[degree1, degree1]; for(int i = degree; i >= 1; i--) { t = 0; for(int j = 1; j <= degree1 - i; j++) { t = t + a[i, i + j] * x[i + j]; x[i] = (1 / a[i, i]) * (b[i] - t); } } double value = x[1]; for(int i = 1; k <= degree; i++) { double n = period; value += x[i + 1] * MathPow(n, i); } Line[iBar] = value; } } double Signal[]; MovingAverage(signal, 0, maMethod, Line,Signal); ArrayResize(Component[0].Value,Data.Bars); Component[0].CompName = "Fast line"; Component[0].DataType = IndComponentType_IndicatorValue; Component[0].FirstBar = iFirstBar; ArrayCopy(Component[0].Value,Line); ArrayResize(Component[1].Value,Data.Bars); Component[1].CompName = "Slow line"; Component[1].DataType = IndComponentType_IndicatorValue; Component[1].FirstBar = iFirstBar; ArrayCopy(Component[1].Value,Signal); ArrayResize(Component[2].Value,Data.Bars); Component[2].FirstBar=iFirstBar; ArrayResize(Component[3].Value,Data.Bars); Component[3].FirstBar=iFirstBar; if(SlotType==SlotTypes_OpenFilter) { Component[2].DataType = IndComponentType_AllowOpenLong; Component[2].CompName = "Is long entry allowed"; Component[3].DataType = IndComponentType_AllowOpenShort; Component[3].CompName = "Is short entry allowed"; } else if(SlotType==SlotTypes_CloseFilter) { Component[2].DataType = IndComponentType_ForceCloseLong; Component[2].CompName = "Close out long position"; Component[3].DataType = IndComponentType_ForceCloseShort; Component[3].CompName = "Close out short position"; } ArrayInitialize(Component[2].Value,0); ArrayInitialize(Component[3].Value,0); IndicatorLogic indLogic=IndicatorLogic_It_does_not_act_as_a_filter; if(ListParam[0].Text=="The fast line rises") indLogic = IndicatorLogic_The_indicator_rises; else if(ListParam[0].Text=="The fast line falls") indLogic = IndicatorLogic_The_indicator_falls; else if(ListParam[0].Text=="The fast line changes its direction upward") indLogic = IndicatorLogic_The_indicator_changes_its_direction_upward; else if(ListParam[0].Text=="The fast line changes its direction downward") indLogic = IndicatorLogic_The_indicator_changes_its_direction_downward; else if(ListParam[0].Text=="The fast line crosses the slow line upward") IndicatorCrossesAnotherIndicatorUpwardLogic(iFirstBar, iPrvs, Line, Signal, Component[2], Component[3]); else if(ListParam[0].Text=="The fast line crosses the slow line downward") IndicatorCrossesAnotherIndicatorDownwardLogic(iFirstBar, iPrvs, Line, Signal, Component[2], Component[3]); else if(ListParam[0].Text=="The fast line is higher than the slow line") IndicatorIsHigherThanAnotherIndicatorLogic(iFirstBar, iPrvs, Line, Signal, Component[2], Component[3]); else if(ListParam[0].Text=="The fast line is lower than the slow line") IndicatorIsLowerThanAnotherIndicatorLogic(iFirstBar, iPrvs, Line, Signal, Component[2], Component[3]); else if(ListParam[0].Text=="The slow line rises") OscillatorLogic(iFirstBar, iPrvs, Signal, 0, 0, Component[2], Component[3], IndicatorLogic_The_indicator_rises); else if(ListParam[0].Text=="The slow line falls") OscillatorLogic(iFirstBar, iPrvs, Signal, 0, 0, Component[2], Component[3], IndicatorLogic_The_indicator_falls); else if(ListParam[0].Text=="The slow line changes its direction upward") OscillatorLogic(iFirstBar, iPrvs, Signal, 0, 0, Component[2], Component[3], IndicatorLogic_The_indicator_changes_its_direction_upward); else if(ListParam[0].Text=="The slow line changes its direction downward") OscillatorLogic(iFirstBar, iPrvs, Signal, 0, 0, Component[2], Component[3], IndicatorLogic_The_indicator_changes_its_direction_downward); else if(ListParam[0].Text=="Price closes above lines") for (int iBar = iFirstBar + iPrvs; iBar < Data.Bars; iBar++) { Component[2].Value[iBar] = Data.Close[iBar - 1] > MathMax(Line[iBar - iPrvs], Signal[iBar - iPrvs]) ? 1 : 0; Component[3].Value[iBar] = Data.Close[iBar - 1] < MathMin(Line[iBar - iPrvs], Signal[iBar - iPrvs]) ? 1 : 0; } else if(ListParam[0].Text=="Price closes below lines") for (int iBar = iFirstBar + iPrvs; iBar < Data.Bars; iBar++) { Component[2].Value[iBar] = Data.Close[iBar - 1] < MathMin(Line[iBar - iPrvs], Signal[iBar - iPrvs]) ? 1 : 0; Component[3].Value[iBar] = Data.Close[iBar - 1] > MathMax(Line[iBar - iPrvs], Signal[iBar - iPrvs]) ? 1 : 0; } else if(ListParam[0].Text=="Price crosses lines upward") for (int iBar = iFirstBar + iPrvs; iBar < Data.Bars; iBar++) { if (Data.Close[iBar - 2] < MathMax(Line[iBar - iPrvs - 1], Signal[iBar - iPrvs - 1])) Component[2].Value[iBar] = Data.Close[iBar - 1] > MathMax(Line[iBar - iPrvs], Signal[iBar - iPrvs]) ? 1 : 0; if (Data.Close[iBar - 2] > MathMin(Line[iBar - iPrvs - 1], Signal[iBar - iPrvs - 1])) Component[3].Value[iBar] = Data.Close[iBar - 1] < MathMin(Line[iBar - iPrvs], Signal[iBar - iPrvs]) ? 1 : 0; } else if(ListParam[0].Text=="Price crosses lines downward") for (int iBar = iFirstBar + iPrvs; iBar < Data.Bars; iBar++) { if (Data.Close[iBar - 2] > MathMin(Line[iBar - iPrvs - 1], Signal[iBar - iPrvs - 1])) Component[2].Value[iBar] = Data.Close[iBar - 1] < MathMin(Line[iBar - iPrvs], Signal[iBar - iPrvs]) ? 1 : 0; if (Data.Close[iBar - 2] < MathMax(Line[iBar - iPrvs - 1], Signal[iBar - iPrvs - 1])) Component[3].Value[iBar] = Data.Close[iBar - 1] > MathMax(Line[iBar - iPrvs], Signal[iBar - iPrvs]) ? 1 : 0; } OscillatorLogic(iFirstBar, iPrvs, Line, dLevel, dLevel, Component[2], Component[3], indLogic); } //+------------------------------------------------------------------+