//+------------------------------------------------------------------+ //| ProjectName | //| Copyright 2012, CompanyName | //| http://www.companyname.net | //+------------------------------------------------------------------+ #property copyright "LineMan" #property link "LineMan" #include //---- defines #define DodgerBlue2 C'0x0d,0x28,0x93' #define Crimson2 C'0xaa,0x14,0x60' //---- indicator settings #property indicator_chart_window #property indicator_buffers 8 #property indicator_color1 Gray #property indicator_color2 Gray #property indicator_color3 DimGray #property indicator_color4 DimGray #property indicator_color5 DarkGray #property indicator_color6 DarkGray #property indicator_color7 DodgerBlue #property indicator_color8 Crimson #property indicator_width1 1 #property indicator_width2 1 #property indicator_width3 2 #property indicator_width4 2 #property indicator_width5 3 #property indicator_width6 3 #property indicator_width7 1 #property indicator_width8 1 //---- indicator parameters extern bool bDispShort = true; // short period LineMan extern bool bDispMid = false; // mid period LineMan extern bool bDispLong = false; // long period LineMan extern bool bAlertDialog = true; // show dialog on signal occur extern bool bAlertSound = true; // play sound on signal occur extern bool bDispTarget = true; // target price of current and next bars extern string sWavAlert = "alert.wav"; // alert sound file name extern int nShortBefore = 2; // short, number of check bars before peaks extern int nShortAfter = 2; // short, number of check bars after peaks extern int nMidBefore = 6; // mid, number of check bars before peaks extern int nMidAfter = 6; // mid, number of check bars after peaks extern int nLongBefore = 24; // long, number of check bars before peaks extern int nLongAfter = 24; // long, number of check bars after peaks extern double marginShort = 2; // short, margin pips extern double marginMid = 5; // mid, margin pips extern double marginLong = 10; // long, margin pips extern double ppPerBar = 1.0; // minimum angles of valid LineMan in (pips/5min) extern color colLineUpper = DodgerBlue; // upper LineMan color extern color colLineLower = Crimson; // lower LineMan color extern color colMarginUpper = DodgerBlue2; // upper margin line color extern color colMarginLower = Crimson2; // lower margin line color extern int styleShort = STYLE_SOLID; // short, line style extern int styleMid = STYLE_DASH; // mid, line style extern int styleLong = STYLE_DASHDOT; // long, line style extern int pointScale = 0; // 0: auto, 1: 123.45, 10: 123.456 extern int nMaxBars = 2000; // maximum number of bars to calculate, 0: no limit //---- indicator buffers double BufferShortUpper[]; // 0: short period, upper peak double BufferShortLower[]; // 1: short period, lower peak double BufferMidUpper[]; // 2: mid period, upper peak double BufferMidLower[]; // 3: mid period, lower peak double BufferLongUpper[]; // 4: long period, upper peak double BufferLongLower[]; // 5: long period, lower peak double BufferSignalLong[]; // 6: Long signal peak double BufferSignalShort[]; // 7: Short signal peak //---- vars string sIndicatorName; string sPrefix; string sIndSelf="00-LineMan_v103"; double point; int markUpper = 217; int markLower = 218; int markLong = 233; int markShort = 234; datetime tAlertLast; //---------------------------------------------------------------------- string TimeFrameToStr(int timeFrame) { switch(timeFrame) { case 1: return("M1"); case 5: return("M5"); case 15: return("M15"); case 30: return("M30"); case 60: return("H1"); case 240: return("H4"); case 1440: return("D1"); case 10080: return("W1"); case 43200: return("MN"); } return("??"); } //---------------------------------------------------------------------- double checkPoint(string sym,int pointScale) { if(pointScale!=0) { // point manually scaled return(Point*pointScale); } // auto scale string s_point001[]= { // point=0.01 pairs, for auto pointScale(0), *JPY are 0.01 as default "EURHUF","USDHUF" }; string s_point0001[]= { // point=0.001 pairs, for auto pointScale(0) "EURCZK","EURHKD","EURSKK","EURZAR","GBPNOK", "GBPSEK","GBPZAR","USDCZK","USDMXN","USDRUB", "USDSKK" }; double point=0; if(StringFind(sym,"JPY")==3) { point=0.01; } else { // check point=0.01 table int n=ArraySize(s_point001); for(int i=0; i=0; i--) { string sName=ObjectName(i); if(StringFind(sName,sPrefix)==0) { ObjectDelete(sName); } } } //---------------------------------------------------------------------- void objLine(string sName,int win,datetime ts,double ps,datetime te,double pe,color col, int width=1,int style=STYLE_SOLID,bool bBack=false,bool bRay=false) { sName=sPrefix+sName; ObjectCreate(sName,OBJ_TREND,win,0,0); ObjectSet(sName,OBJPROP_TIME1,ts); ObjectSet(sName,OBJPROP_PRICE1,ps); ObjectSet(sName,OBJPROP_TIME2,te); ObjectSet(sName,OBJPROP_PRICE2,pe); ObjectSet(sName,OBJPROP_COLOR,col); ObjectSet(sName,OBJPROP_WIDTH,width); ObjectSet(sName,OBJPROP_STYLE,style); ObjectSet(sName,OBJPROP_BACK,bBack); ObjectSet(sName,OBJPROP_RAY,bRay); } //---------------------------------------------------------------------- void objText(string sName,int win,datetime t,double p,string text,color col,int fontSize=10,string fontName="Arial") { sName=sPrefix+sName; ObjectCreate(sName,OBJ_TEXT,win,0,0); ObjectSetText(sName,text,fontSize,fontName,col); ObjectSet(sName,OBJPROP_TIME1,t); ObjectSet(sName,OBJPROP_PRICE1,p); } //---------------------------------------------------------------------- bool isUpperFractal2(int i) { double hi0=High[i]; if(hi0> High[i - 1] && hi0 > High[i - 2]) { if(hi0 > High[i + 1] && hi0 > High[i + 2]) { return(true); } if(hi0==High[i+1] && hi0>High[i+2] && hi0>High[i+3]) { return(true); } if(hi0>= High[i + 1] && hi0 == High[i + 2]) { if(hi0>High[i + 3] && hi0> High[i + 4]) { return(true); } if(hi0==High[i+3] && hi0>High[i+4] && hi0>High[i+5]) { return(true); } if(hi0>=High[i+3] && hi0==High[i+4] && hi0>High[i+5] && hi0>High[i+6]) { return(true); } } } return(false); } //---------------------------------------------------------------------- bool isLowerFractal2(int i) { double lo0=Low[i]; if(lo0< Low[i - 1] && lo0 < Low[i - 2]) { if(lo0 < Low[i + 1] && lo0 < Low[i + 2]) { return(true); } if(lo0==Low[i+1] && lo0hi) { bPeak=false; break; } } if(bPeak) { for(j=1; j<=nAfter; j++) { x= i - j; if(x<0 || High[x]>=hi) { bPeak=false; break; } } } return(bPeak); } //---------------------------------------------------------------------- bool isLowerPeak(int i,int nBefore,int nAfter) { if(nBefore==2 && nAfter==2) { // original iFractal() return(isLowerFractal2(i)); } bool bPeak=true; double lo =Low[i]; for(int j=1; j<=nBefore; j++) { int x=i+j; if(Low[x]>0) &0x0ff); } //---------------------------------------------------------------------- int getG(color col) { return((col>>8) &0x0ff); } //---------------------------------------------------------------------- int getB(color col) { return((col>>16) &0x0ff); } //---------------------------------------------------------------------- void darken(color &col,double c=0.5) { int r = getR(col) * c; int g = getG(col) * c; int b = getB(col) * c; col=RGB(r,g,b); } //---------------------------------------------------------------------- void lineMan(int idx,int limit,string sName,bool bDisp,bool bSignal,int nBefore,int nAfter, double margin,double &BufferUpper[],double &BufferLower[],int w,int style) { static datetime s_tsUpper[3],s_teUpper[3]; static datetime s_tsLower[3],s_teLower[3]; int iupper1 = EMPTY_VALUE; int iupper2 = EMPTY_VALUE; int ilower1 = EMPTY_VALUE; int ilower2 = EMPTY_VALUE; if(bDisp) { for(int i=MathMax(limit-1,nAfter+5); i>=nAfter; i--) { double upper = EMPTY_VALUE; double lower = EMPTY_VALUE; if(isUpperPeak(i,nBefore,nAfter)) { upper=High[i]; } if(isLowerPeak(i,nBefore,nAfter)) { lower=Low[i]; } BufferUpper[i] = upper; BufferLower[i] = lower; } findPeak(iupper1,iupper2,BufferUpper,nAfter); findPeak(ilower1,ilower2,BufferLower,nAfter); } if(iupper1==EMPTY_VALUE || iupper2==EMPTY_VALUE || ilower1==EMPTY_VALUE || ilower2==EMPTY_VALUE) { // not found return; } datetime tsUpper = Time[iupper1]; datetime teUpper = Time[iupper2]; double psUpper = High[iupper1]; double peUpper = High[iupper2]; datetime tsLower = Time[ilower1]; datetime teLower = Time[ilower2]; double psLower = Low[ilower1]; double peLower = Low[ilower2]; if(iupper2==EMPTY_VALUE) { psUpper = 0; peUpper = 0; } if(ilower2==EMPTY_VALUE) { psLower = 0; peLower = 0; } bool bUpperChanged = (s_tsUpper[idx] != tsUpper || s_teUpper[idx] != teUpper); bool bLowerChanged = (s_tsLower[idx] != tsLower || s_teLower[idx] != teLower); s_tsUpper[idx] = tsUpper; s_teUpper[idx] = teUpper; s_tsLower[idx] = tsLower; s_teLower[idx] = teLower; datetime t1 = Time[1]; datetime t0 = Time[0]; datetime t00= Time[0]+Period() * 60; double close1 = Close[1]; double close0 = Close[0]; double hi1 = High[1]; double lo1 = Low[1]; double psMargin,peMargin,psu,peu,psl,pel,psm,pem; double pm00,pm0,pm1; int ww; // upper { // line if(margin!=0.0) { psMargin = psUpper + margin * point; peMargin = peUpper + margin * point; psu = psUpper; peu = peUpper; psm = psMargin; pem = peMargin; } else { psMargin = 0; peMargin = 0; psu = psUpper; peu = peUpper; psm = psu; pem = peu; } color colMargin=colMarginUpper; color colLine=colLineUpper; ww=w; if(peu>=psu) { ww = 1; darken(colMargin); darken(colLine); } objLine(sName+" upper margin",0,tsUpper,psMargin,teUpper,peMargin,colMargin,1,STYLE_DOT,true,true); objLine(sName+" upper",0,tsUpper,psUpper,teUpper,peUpper,colLine,ww,style,true,true); // check signal, Long tsUpper = Time[0] - iupper1 * Period() * 60; teUpper = Time[0] - iupper2 * Period() * 60; double a=(peu-psu)/(teUpper-tsUpper); // (pips/sec) pm1 = psm + a * (t1 - tsUpper); pm0 = psm + a * (t0 - tsUpper); pm00= psm+a *(t00-tsUpper); if(bSignal) { bool bValid=(a*Period()*60<=-ppPerBar*point); if(bValid && bDispTarget) { double dtxLine = Period() * 60 * 2; double dtxText = Period() * 60 * 4; double dpyLine0 =(WindowPriceMax() - WindowPriceMin())*0.05; double dpyText0=dpyLine0+3*point; // add offset double dpyLine00 =dpyLine0 / 2; double dpyText00=dpyLine00+3*point; // add offset objLine(sName+" upline target0 a",0,t0+Period()*60,pm0,t0,pm0,colLineUpper); objLine(sName+" upline target0 b",0,t0,pm0,t0+dtxLine,pm0+dpyLine0,colLineUpper); objText(sName+" uptext target0",0,t0+dtxText,pm0+dpyText0,DoubleToStr(pm0,Digits),colLineUpper); objLine(sName+" upline target00 a",0,t00+Period()*60,pm00,t00,pm00,colLineUpper); objLine(sName+" upline target00 b",0,t00,pm00,t00+dtxLine,pm00+dpyLine00,colLineUpper); objText(sName+" uptext target00",0,t00+dtxText,pm00+dpyText00,DoubleToStr(pm00,Digits),colLineUpper); } else { objLine(sName+" upline target0 a",0,0,0,0,0,Black); objLine(sName+" upline target0 b",0,0,0,0,0,Black); objText(sName+" uptext target0",0,0,0,0,0,Black); objLine(sName+" upline target00 a",0,0,0,0,0,Black); objLine(sName+" upline target00 b",0,0,0,0,0,Black); objText(sName+" uptext target00",0,0,0,0,0,Black); } if(bValid && ((close1=pm0)) { BufferSignalLong[0]=Low[0]-iATR(NULL,0,14,0); if(t0 !=tAlertLast) { if(bAlertSound) { PlaySound(sWavAlert); } if(bAlertDialog) { Alert(Symbol()+", Long signal, LineMan= ",peu,", prev hi= ",High[iupper2],", prev lo= ",Low[ilower2]); } tAlertLast=t0; } } else { BufferSignalLong[0]=EMPTY_VALUE; } } } // lower { // line if(margin!=0.0) { psMargin = psLower - margin * point; peMargin = peLower - margin * point; psl = psLower; pel = peLower; psm = psMargin; pem = peMargin; } else { psMargin = 0; peMargin = 0; psl = psLower; pel = peLower; psm = psl; pem = pel; } colMargin=colMarginLower; colLine=colLineLower; ww=w; if(pel<=psl) { ww = 1; darken(colMargin); darken(colLine); } objLine(sName+" lower",0,tsLower,psLower,teLower,peLower,colLine,ww,style,true,true); objLine(sName+" lower margin",0,tsLower,psMargin,teLower,peMargin,colMargin,1,STYLE_DOT,true,true); // check signal, Short tsLower = Time[0] - ilower1 * Period() * 60; teLower = Time[0] - ilower2 * Period() * 60; a=(pel-psl)/(teLower-tsLower); // (pips/sec) pm1 = psm + a * (t1 - tsLower); pm0 = psm + a * (t0 - tsLower); pm00= psm+a *(t00-tsLower); if(bSignal) { bValid=(a*Period()*60>=ppPerBar*point); if(bValid && bDispTarget) { dtxLine = Period() * 60 * 5; dtxText = Period() * 60 * 7; dpyLine0 =(WindowPriceMax() - WindowPriceMin())*0.05; dpyText0=dpyLine0; // no offset dpyLine00 =dpyLine0 / 2; dpyText00=dpyLine00; // no offset objLine(sName+" loline target0 a",0,t0+Period()*60,pm0,t0,pm0,colLineLower); objLine(sName+" loline target0 b",0,t0,pm0,t0+dtxLine,pm0-dpyLine0,colLineLower); objText(sName+" lotext target0",0,t0+dtxText,pm0-dpyText0,DoubleToStr(pm0,Digits),colLineLower); objLine(sName+" loline target00 a",0,t00+Period()*60,pm00,t00,pm00,colLineLower); objLine(sName+" loline target00 b",0,t00,pm00,t00+dtxLine,pm00-dpyLine00,colLineLower); objText(sName+" lotext target00",0,t00+dtxText,pm00-dpyText00,DoubleToStr(pm00,Digits),colLineLower); } else { objLine(sName+" loline target0 a",0,0,0,0,0,Black); objLine(sName+" loline target0 b",0,0,0,0,0,Black); objText(sName+" lotext target0",0,0,0,0,0,Black); objLine(sName+" loline target00 a",0,0,0,0,0,Black); objLine(sName+" loline target00 b",0,0,0,0,0,Black); objText(sName+" lotext target00",0,0,0,0,0,Black); } if(bValid && ((close1>=pm1 || bLowerChanged) && close0