//+---------------------+ //| LSMA | //| Optimized for speed | //| by Robert Hill | //| | //| Added Arrows at | //| cross of 0 line | //| and Level Lines | //+---------------------+ #property copyright "Copyright 2005 Ron Thompson" #property link "http://www.forexmt4.com/" // indicator settings #property indicator_separate_window // buffers #property indicator_buffers 2 #property indicator_color1 Aqua #property indicator_color2 Red #property indicator_width1 1 #property indicator_width2 1 // user input extern int xbars = 500; extern int PeriodGo = 1; extern int PeriodStop = 200; extern int UseOpenPrice = 1; extern double LevelLinesPercent = 75; extern string m = "--Moving Average Types--"; extern string m0 = " 0 = SMA"; extern string m1 = " 1 = EMA"; extern string m2 = " 2 = SMMA"; extern string m3 = " 3 = LWMA"; extern int MA_Type=0; extern int MA_Period = 21; extern color BuyColor = Green; extern color SellColor = Red; extern int distBelow = 5; extern int distAbove = 50; // bar counting datetime bartime=0; // Objects int uniq=0; string Object_ID = "LSMA200VFast3_"; // LSMA int per; // buffers double buff1[]; double MA_Buffer[]; double sumX[]; // Collect sum for each period double sumX2[]; double sumY[]; double sumY2[]; double sumXY[]; // Collect wt for each period double wt[]; //LSMA current value double wtp[]; //LSMA previous value int MAType; double myPoint; string Id = "VoteB"; double Buy1, Buy2, Sell1, Sell2; //+-----------+ //| Init | //+-----------+ int init() { // 233 up arrow // 234 down arrow // 158 little dot // 159 big dot // 168 open square // 120 box with X double tmp; myObjectsDeleteAll(); //---- Add 2 additional buffers as helpers used for counting. // 1 for plotting, 7 helper IndicatorBuffers(8); SetIndexBuffer(0,buff1); SetIndexStyle(0, DRAW_LINE); SetIndexBuffer(1, MA_Buffer); SetIndexStyle(1, DRAW_LINE); SetIndexBuffer(2, sumX); SetIndexBuffer(3, sumX2); SetIndexBuffer(4, sumY); SetIndexBuffer(5, sumXY); SetIndexBuffer(6, wt); SetIndexBuffer(7, wtp); tmp = PeriodStop * LevelLinesPercent / 100.0; Buy1 = 0.0; Buy2 = -tmp; Sell1 = 0.0; Sell2 = tmp; SetLevelStyle(STYLE_DASH, 1, Gray); SetLevelValue(0,Buy2); SetLevelValue(1, Sell2); SetLevelValue(2, 0.0); //SetIndexArrow(0,159); myPoint = SetPoint(); if (MA_Type > 3) MAType = 0; Print("Init complete"); } //+-----------+ //| DE-Init | //+-----------+ int deinit() { myObjectsDeleteAll(); Print("DE-Init complete"); } //+-----------+ //| Each Tick | //+-----------+ int start() { int pos; int vote; // draw once at open of bar // if(bartime==Time[0]) return(0); // bartime=Time[0]; myObjectsDeleteAll(); uniq=0; for(pos = xbars; pos >= 0; pos--) { vote=0; calcLSMAs(pos); calcLSMAsPrev(pos); for (int j = PeriodGo; j <= PeriodStop; j++) { if(wt[j]>wtp[j]) vote++; if(wt[j]= Sell1 && buff1[pos] <= Sell1) { ObjectCreate(Id+uniq, OBJ_TEXT, 0, Time[pos],Low[pos]-distBelow*Point ); ObjectSetText(Id+uniq, CharToStr(242), 10, "Wingdings", SellColor); uniq++; } if (buff1[pos + 1] >= Sell2 && buff1[pos] <= Sell2) { ObjectCreate(Id+uniq, OBJ_TEXT, 0, Time[pos],Low[pos]-distBelow*Point ); ObjectSetText(Id+uniq, CharToStr(234), 10, "Wingdings", SellColor); uniq++; } // Up Arrow if (buff1[pos+1] <= Buy1 && buff1[pos] >= Buy1) { ObjectCreate(Id+uniq, OBJ_TEXT, 0, Time[pos],High[pos]+distAbove*Point ); ObjectSetText(Id+uniq, CharToStr(241), 10, "Wingdings", BuyColor); uniq++; } if (buff1[pos+1] <= Buy2 && buff1[pos] >= Buy2) { ObjectCreate(Id+uniq, OBJ_TEXT, 0, Time[pos],High[pos]+distAbove*Point ); ObjectSetText(Id+uniq, CharToStr(233), 10, "Wingdings", BuyColor); uniq++; } }//for pos ArraySetAsSeries(buff1, true); for(pos = xbars; pos >= 0; pos--) { MA_Buffer[pos] = iMAOnArray(buff1,0,MA_Period, 0, MAType, pos ); } }//start // Calculate all LSMAs for the previous candle void calcLSMAsPrev(int mybar) { int i; double Val = 0; double c, m, yint, mywt; // Clear working buffers for(i = 0; i <= PeriodStop ; i++) { sumX[i] = 0; sumY[i] = 0; sumXY[i] = 0; sumX2[i] = 0; sumY2[i] = 0; } // Then calculate all sums realizing that // The sum for period 1 is the current value // the sum for period 2 is the sum for period 1 + the previous value // the sum for period 3 is the sum for period 2 + the previous value for(i = 1; i <= PeriodStop ; i++) { if (UseOpenPrice == 1) Val = Open[mybar+i]; else Val = Close[mybar+i+1]; sumY[i] = sumY[i-1] + Val; sumY2[i] = sumY2[i-1] + Val * Val; sumX[i] = sumX[i-1] + i; sumX2[i] = sumX2[i - 1] + i * i; sumXY[i] = sumXY[i-1] + Val * i; } // Then calculate the LSMA value for each period for(i = 1; i <= PeriodStop ; i++) { c=sumX2[i] * i - sumX[i] * sumX[i]; if(c==0.0) c = .0000001; m = (sumXY[i] * i - sumX[i] * sumY[i]) /c; yint=(sumY[i] - sumX[i] * m) / i; mywt = yint + m * i; // Round value to nearest pip for accurate compares later mywt = MathFloor(mywt/myPoint)*myPoint; wtp[i] = mywt; } } // Calculate all LSMAs for the current candle void calcLSMAs(int mybar) { int i; double Val = 0; double c, m, yint, mywt; // Clear working buffers for(i = 0; i <= PeriodStop ; i++) { sumX[i] = 0; sumY[i] = 0; sumXY[i] = 0; sumX2[i] = 0; sumY2[i] = 0; } // Then calculate all sums realizing that // The sum for period 1 is the current value // the sum for period 2 is the sum for period 1 + the previous value // the sum for period 3 is the sum for period 2 + the previous value for(i = 1; i <= PeriodStop ; i++) { if (UseOpenPrice == 1) Val = Open[mybar+i-1]; else Val = Close[mybar+i]; sumY[i] = sumY[i-1] + Val; sumY2[i] = sumY2[i-1] + Val * Val; sumX[i] = sumX[i-1] + i; sumX2[i] = sumX2[i-1] + i * i; sumXY[i] = sumXY[i - 1] + Val * i; } // Then calculate the LSMA value for each period for(i = 1; i <= PeriodStop ; i++) { c=sumX2[i] * i - sumX2[i]; if(c==0.0) c = .0000001; m = (sumXY[i] * i - sumX[i] * sumY[i]) /c; yint=(sumY[i] - sumX[i] * m) / i; mywt = yint + m * i; // Round value to nearest pip for accurate compares later mywt = MathFloor(mywt/myPoint)*myPoint; wt[i] = mywt; } } void myObjectsDeleteAll() { int obj = ObjectsTotal(OBJ_TEXT); int i, limit; string objName; if (obj > 0) { for (i = obj; i >= 0;i--) { objName = ObjectName(i); if (StringFind(objName,Object_ID, 0) >= 0) ObjectDelete(objName); } } limit=1500; for(i=limit; i>=0; i--) ObjectDelete(Id+i); } double SetPoint() { double mPoint; if (Digits < 4) mPoint = 0.01; else mPoint = 0.0001; return(mPoint); }