{ Indicator: _LRDeviation.RS Description : Plots the deviation between current Price and Linear Regression line, expressed in units of various functions. Note: Format - General Tab - Load additional data must be at least >= Offset specified in input parameters Provided By: MarkSanDiego Updated: 05/28/12 original version 11/10/12 LinearRegFaster function substituted for LinearReg function 12/14/12 calculating functions without offset provides greater flexibility in using indicator with both historical and real data 12/26/12 minimal change 01/16/13 clean up code 01/20/13 user can now specify default color for non-highlighted columns. I prefer lightgray instead of white, which is a bit too bright. 10/09/15 minor corrections to various formulas used to calculate projected profit and risk. } Input: Price(close), RefPrice(AvgPrice), RefSmooth(0), Offset(6), LRLength(80), { linear regression function length } DevID(2), { deviation function identifier } StdDevLength(0), { standard deviation length at Offset bar} StdErrLength(0), { standard error length at Offset bar} ATRLength(14), { average true range length at Offset Bar } JATRLength(14), { Jurik moving average true range length } Percent(1), { percentage of LR centerline Price at Offset bar } Pts(1), { points } UseAlertColors(true), { color code deviation from price, according to defined deviation alerts } Dev1Alert(1.5), Dev2Alert(2.0), Dev3Alert(2.5), Dev4Alert(3.0), DevLevelMin(0), { 0 = ignore, otherwise display only DevLevel specified by range DevLevelMin to DevLevelMax } DevLevelMax(0), { 0 = ignore, otherwise display only DevLevel specified by range DevLevelMin to DevLevelMax } SwingLength1(10), { Estimated number of bars needed to complete a quick swing trade } SwingLength2(20), { Estimated number of bars needed to complete a longer swing trade } SwingDevMult(4), { Estimated total number of deviation units traversed by successful swing trade } int ReCalcSeconds(5), { function recalculation interval during real time data } DefaultColor(lightgray), DefaultBGColor(black); Vars: intrabarpersist Dir(0), intrabarpersist Length(LRLength), { Length of linear regression center line } Intrabarpersist YrLength(0), { LRLength expressed in years } intrabarpersist ROCProfit1(0), { Profit resulting from trend rate of change if Trade completes in SwingLength1 bars } intrabarpersist ROCProfit2(0), { Profit resulting from trend rate of change if Trade completes in SwingLength2 bars } intrabarpersist SwingProfit(0), { Profit resulting from price moving from -2 SE units deviation to +2 SE unit deviation from LR center line } intrabarpersist TotalProfit1(0), { Total profit resulting from swing trade occurring within SwingLength1 bars plus SwingProfit } intrabarpersist TotalProfit2(0), { Total profit resulting from swing trade occurring within SwingLength2 bars plus SwingProfit } intrabarpersist RiskPct(0), { Risk (%) of entering trade at -2 SE units deviation, If Stop is set at -3 SE units deviation } intrabarpersist RiskReward1(0), { = TotalProfit1 / RiskPct } intrabarpersist RiskReward2(0), { = TotalProfit2 / RiskPct } intrabarpersist BEBars(0), { number of bars after entry that trailing stop will be at break even } intrabarpersist x(0), intrabarpersist oRef(0), { LR Centerline Value1 at End of LR centerline plus Offset bars to right (Current bar) } intrabarpersist oRef2(0), { LRLength Centerline value at end of LR without Offset } intrabarpersist oDev(0), { Value of deviation from LR center line with offset } intrabarpersist oDev2(0), { Value1 of deviation of LR center line without offset } intrabarpersist oUnitdev(0), { Single unit of deviation at Offset Bar } intrabarpersist oUnitDev2(0), { single unit of deviation without offset } intrabarpersist oLRSlope(0), { slope of the linear regression center line } intrabarpersist oLRSlope2(0), { slope of linear regression center line without offset } intrabarpersist oLRAngle(0), { angle of linear regression center line without offset } intrabarpersist oLRAngle2(0), { angle of linear regression center line without offset } intrabarpersist oLRIntercept(0), { beginning LR centerline value with specified offset } intrabarpersist Count(0), intrabarpersist oMean(0), { holding variable For function _StdDevMean, currently not used } intrabarpersist BS(0), { holds BarStatus(1) } intrabarpersist ROC(0), { lienar regression line rate of change as percentage } intrabarpersist Gain(0), { ROC x Length of LR channel } intrabarpersist AnnGain(0), { annualized gain } intrabarpersist RTData(false), { true, if real time data } intrabarpersist L1(0), { adjusted standard deviation length } intrabarpersist L2(0), { adjust standard error length } intrabarpersist PlotColor(lightgray), intrabarpersist PlotBGColor(black); { Methods begin //////////////////////////////////////////////////////////////////////////////////////////////////// } var: elsystem.Timer Timer1( NULL ), intrabarpersist bool Calc(false); { true if calculation should be performed } Method override void InitializeComponent() begin Timer1 = new elsystem.Timer; Timer1.Interval = ReCalcSeconds * 1000; Timer1.AutoReset = true; Timer1.Enable = true; Timer1.Name = "Timer1"; Timer1.elapsed += Timer1_Elapsed; end; { run once every CalcSeconds seconds} {The Elapsed event handler is called when the timer counts down to zero} Method void Timer1_Elapsed( elsystem.Object sender, elsystem.TimerElapsedEventArgs args ) begin // BS = -1; { all timer generated executions associated with BarStatus(1) = -1 (undefined) } Calc = true; end; Method void LRDeviation() begin { calculate linear regression line parameters and deviation units for the offset bar } { oRef is centerline value at current bar } { oRef2 is centerline value at Offset bar } { oLRSlope, oLRAngle are calculated at Offset bar } { oLRIntercept is left most value of linear regression centerline } { LRTgrBar = -Offset } Value1 = _LinearRegFaster( RefPrice[Offset], LRLength, -Offset, oLRSlope, oLRAngle, oLRIntercept, oRef) ; { LRTgrBar = -Offset } Once Begin switch DevID begin Case 1: { StdDev Length must be >= 2. If not specified, use LRLength } L1 = MaxList(2, iff(StdDevLength > 0, StdDevLength, LRLength)); Case 2: { StdErr Length must be >= 3. If not specified, use LRLength } L2 = MaxList(3, iff(StdErrLength > 0, StdErrLength, LRLength)); end; YrLength = (DateToJulian(Date) - DateToJulian(Date[LRLength]))/365; end; { deviation calculations are occurring at offset bar, not current bar } switch DevID begin Case 0: oUnitDev = 1; { raw deviation without processing } Case 1: value1 = _StdDevMean(RefPrice[Offset], L1, 1, oMean, oUnitDev); Case 2: oUnitDev = _StdError(RefPrice[Offset], L2); Case 3: oUnitDev2 = _AvgTrueRange(ATRLength); oUnitdev = oUnitDev2[Offset]; { uncomment the next 3 lines if you have purchased Jurik Moving Average functions } // case 4: // oUnitDev2 = _JMATrueRange(JATRLength); // oUnitDev = oUnitDev2[Offset]; Case 5: oUnitDev = oRef * Percent / 100; Case 6: oUnitDev = Pts; end; end; Method void Calculations() begin count = count + 1; { unit deviation and slope values calculated at the offset bar, where they will NOT be influenced by the most recent Offset bars } { price deviation is calculated with LR centerline projected right to current bar } oRef2 = oLRIntercept + oLRSlope * (Length - 1); { calculate deviation and direction of trend at current bar, not offset bar } if oUnitDev <> 0 then oDev = (Price - oRef)/oUnitDev; Dir = sign(oLRSlope); { calculate swing component of profit, risk and ROC for long and short trades } x = oUnitdev * SwingDevMult / 2; { future rate of change per bar in % } { note that rate of change is based on "starting" point for trade entry} { risk calc for LE assumes entry at -2 deviation units and stop loss at -3 deviation units from center line } Switch Dir begin Case 1: { long } SwingProfit = (oRef + x ) / (oRef - x) - 1; RiskPct = oUnitDev / (oRef - x); if (oRef - x) <> 0 then ROC = oLRSlope / (oRef - x); if oLRIntercept <> 0 then Gain = (oRef2/oLRIntercept - 1) * Dir; Case -1: { Short } SwingProfit = 1 - (oRef - x ) / (oRef + x); RiskPct = oUnitDev / (oRef + x); if (oRef + x) <> 0 then ROC = oLRSlope / (oRef + x); If oLRIntercept <> 0 then Gain = (1 - oRef2/oLRIntercept) * Dir; end; { calculate Gain from begnning to end of centerline, and annualized } if YrLength <> 0 then AnnGain = Gain / YrLength; ROCProfit1 = Absvalue(ROC * SwingLength1); ROCProfit2 = Absvalue(ROC * SwingLength2); { calculate total profits } TotalProfit1 = ROCProfit1 + SwingProfit; TotalProfit2 = ROCProfit2 + SwingProfit; { calculate RiskRewards } RiskReward1 = TotalProfit1 / RiskPct; RiskReward2 = TotalProfit2 / RiskPct; { calculate number of bars before trailing stop is at break even } If ROC <> 0 then BEBars = AbsValue(RiskPct/ROC); { alerts } If UseAlertColors then begin switch oDev begin case >= Dev4Alert: PlotColor = black; PlotBGColor = green; Case >= Dev3Alert: PlotColor = green; PlotBGColor = black; Case >= Dev2Alert: PlotColor = black; PlotBGColor = red; Case >= Dev1Alert: PlotColor = red; PlotBGColor = black; Case <= - Dev4Alert: PlotColor = black; PlotBGColor = red; Case <= -Dev3Alert: PlotColor = red; PlotBGColor = black; Case <= -Dev2Alert: PlotColor = black; PlotBGColor = green; Case <= -Dev1Alert: PlotColor = green; PlotBGColor = black; Default: PlotColor = DefaultColor; PlotBGColor = DefaultBGColor; end; end; end; { Method RealTimeCalculations } Method void Plotter() begin plot1(Length, "Len", yellow); plot2(Offset, "xOff", DefaultColor); plot3(-Offset, "Tgt", DefaultColor); plot4(oDev,"Dev"); plot5(ROC, "ROC", DefaultColor); plot6(Gain, "Gain", DefaultColor); plot7(AnnGain, "Ann Gain", DefaultColor); plot8(SwingLength1, "Swing Len 1", yellow); plot9(ROCProfit1, "ROC P1", DefaultColor); plot10(SwingLength2, "Swing Len 2", yellow); plot11(ROCProfit2, "ROC P2", DefaultColor); plot12(SwingProfit, " P3 = SEx4", DefaultColor); plot13(TotalProfit1, "Profit 1", DefaultColor); plot14(TotalProfit2, "Profit 2", DefaultColor); plot15(RiskPct, "Risk", DefaultColor); plot16(RiskReward1, "Rsk Rwd 1", DefaultColor); plot17(RiskReward2, "Rsk Rwd 2", DefaultColor); plot18(BEBars, "BE Bars", DefaultColor); plot19(ReCalcSeconds, "Calc Sec", yellow); { { debug - may comment these out, or hide outputs using indicator Formatting } plot20(oLRSlope,"LR Slope", DefaultColor); plot30(oRef, "oRef"); plot31(oRef2,"oRef2"); plot32(oUnitDev, "UnitDev"); plot33(x, "X"); plot34(oRef + x, "oRef + x"); plot35(oref - x, "oRef - x"); plot36(oLRSlope, "oLRSlope"); plot37(Date[Offset], "Date[xOff]"); plot38(Price, "Price"); plot39(BS, "BS"); plot40(count, "Count"); plot41(oLRIntercept, "Intercept"); plot42(YrLength, "YRLength"); plot43(oRef + oLRslope*SwingLength1,"CL Swing1"); plot44(oRef + oLRslope*SwingLength2,"CL Swing2"); plot45(YrLength,"YrLength"); } SetPlotColor(4, PlotColor); SetPlotBGColor(4, PlotBGColor); SetPlotBGColor(1, blue); SetPlotBGColor(8, blue); SetPlotBGColor(10, blue); SetPlotColor(15, black); SetPlotBGColor(15, red); end; { Method Plotter } { Methods end //////////////////////////////////////////////////////////////////////////////////////////////////// } #region Main Program BS = BarStatus(1); Switch BS begin Case 1: #region Tick Processing #region Triggered Calculations { Calculate immediately at start of real time data } once begin Calc = true; LRDeviation(); end; If Calc then begin Calculations(); Calc = false; end; #endregion; #region Plotting If (DevLevelMin = 0 and DevLevelMax = 0) OR (oDev >= DevLevelMin AND oDev <= DevLevelMax) then begin Plotter(); end; #endregion #endregion { Tick Processing } Case 2: #region EndOfBar Processing LRDeviation(); Calculations(); If (DevLevelMin = 0 and DevLevelMax = 0) OR (oDev >= DevLevelMin AND oDev <= DevLevelMax) then begin Plotter(); end; #endregion end; #endregion { Main Program }