/*[[ Name := RSTD Signal to Noise Ratio Author := Luis Damiani et al Notes := Signal to Noise Ratio. lag = 4 bars Separate Window := Yes First Color := DarkGreen First Draw Type := Line First Symbol := 217 Use Second Data := Yes Second Color := DimGray Second Draw Type := Line Second Symbol := 218 Minimum Chart Limits := -15 Maximum Chart Limits := 35 ]]*/ input: maxbars(300),showlag(0); Variable : shift(0), prevbars(0), first(True), loopbegin(0),comm(0), i(0), Detrender(0), I1(0), Q1(0), jI(0), jQ(0), CurI2(0), CurQ2(0), I2p(0), Q2p(0), I2(0), Q2(0),Q3(0),I3(0), CurRe(0), CurIm(0), Re(0), Im(0),cnt(0), CurPer(0), Per(0), SmoothPeriod(0), Signal(0),Noise(0),SNR(0),pos(0); Arrays : I1p[7](0), Q1p[7](0), Detp[7](0),Q3p[35](0); SetLoopCount(0); // check conditions are ok. if Bars < 6 or prevbars = bars then exit; // check for additional bars loading or total reloading If Bars > prevbars Or comm!=Symbol Then first = True; prevbars = bars; comm=symbol; If first Then Begin // loopbegin prevent counting of counted bars exclude current loopbegin = maxbars-6; first = False; SmoothPeriod = Per; End Else Begin loopbegin = Bars-prevbars; End; // loop from first bar to the current bar For shift=loopbegin Downto 0 Begin if shift > 0 then begin for i=6 DownTo 2 begin I1p[i] = I1p[i-1]; Q1p[i] = Q1p[i-1]; Detp[i] = Detp[i-1]; end; end; I2p = I2; Q2p = Q2; //HILBERT TRANSFORM BEGIN // Smothing and calculating detrender Detrender = (0.0962*iMAEx(4, MODE_LWMA, 0, PRICE_MEDIAN, shift)+ 0.5769*iMAEx(4, MODE_LWMA, 0, PRICE_MEDIAN, shift+2) - 0.5769*iMAEx(4, MODE_LWMA, 0, PRICE_MEDIAN, shift+4)- 0.0962*iMAEx(4, MODE_LWMA, 0, PRICE_MEDIAN, shift+6)) * (0.075*Per + 0.54); // Compute InPhase and Quadrature components I1 = Detp[3]; Q1 = (0.0962*Detrender + 0.5769*Detp[2] - 0.5769*Detp[4] - 0.0962*Detp[6]) * (0.075*Per + 0.54); if shift > 0 then begin I1p[1] = I1; Q1p[1] = Q1; Detp[1] = Detrender; end; //HILBERT TRANSFORM END // Advance the phase of I1 and Q1 by 90 degrees jI = (0.0962*I1 + 0.5769*I1p[2] - 0.5769*I1p[4] - 0.0962*I1p[6])*(0.075*Per + 0.54); jQ = (0.0962*Q1 + 0.5769*Q1p[2] - 0.5769*Q1p[4] - 0.0962*Q1p[6])*(0.075*Per + 0.54); // Phasor addition for 3 bar averaging CurI2 = I1 - jQ; CurQ2 = Q1 + jI; // Smooth the I and Q components before applying the discriminator I2 = 0.2*CurI2 + 0.8*I2; Q2 = 0.2*CurQ2 + 0.8*Q2; // Homodyne Discriminator CurRe = I2*I2p + Q2*Q2p; CurIm = I2*Q2p - Q2*I2p; Re = 0.2*CurRe + 0.8*Re; Im = 0.2*CurIm + 0.8*Im; if (Im != 0 and Re != 0) then CurPer = 6.2832 / ArcTan(Im/Re); if (CurPer > 1.5*Per) then CurPer = 1.5*Per; if (CurPer < 0.67*Per) then CurPer = 0.67*Per; if CurPer < 6 then CurPer = 6.0; if CurPer > 50 then CurPer = 50.0; Per = 0.2*CurPer + 0.8*Per; SmoothPeriod = 0.33*Per + 0.67*SmoothPeriod; // Code specific to SNR Q3=0.5*(iMAEx(4, MODE_LWMA, 0, PRICE_MEDIAN, shift) - iMAEx(4, MODE_LWMA, 0, PRICE_MEDIAN, shift+2))* (0.1759*SmoothPeriod+0.4607); I3=0; if shift > 0 then { for i=34 DownTo 1 begin Q3p[i] = Q3p[i-1]; end; }; Q3p[0]=Q3; for cnt = 0 to Floor(SmoothPeriod/2)-1 Begin I3=I3+Q3p[cnt]; end; I3=1.57*I3/ Floor(SmoothPeriod/2); Signal=I3*I3+Q3*Q3; Noise = 0.1*(H[0]-L[0])*(H[0]-L[0])*0.25+0.9*Noise; if(Noise != 0 and Signal != 0) then SNR= 0.33*(10*log(Signal/Noise)/log(10))+0.67*SNR; if showlag=1 then pos=shift+4 else pos=shift; SetIndexValue(pos, SNR); SetIndexValue2(pos, 6); // loopbegin--; End;