Confluence.efs EFSLibrary - Discussion Board
File Name: Confluence.efs
Description:
Confluence
Formula Parameters:
Price Data To Use : Close
Harmonic : 10
Notes:
This is modified version of Dale Legan's "Confluence" indicator written by Gary Fritz.
Download File:
Confluence.efs
EFS Code:
/********************************* Provided By: eSignal (Copyright c eSignal), a division of Interactive Data Corporation. 2009. All rights reserved. This sample eSignal Formula Script (EFS) is for educational purposes only and may be modified and saved under a new file name. eSignal is not responsible for the functionality once modified. eSignal reserves the right to modify and overwrite this EFS file with each new release. Description: Confluence Version: 1.0 04/01/2009 Formula Parameters: Default: Price Data To Use Close Harmonic 10 Notes: This is modified version of Dale Legan's "Confluence" indicator written by Gary Fritz. ================================================================ Here is Gary`s commentary: * I moved the core Confluence computations into a Confluence function. Since the Confluence indicator returned several "states" (bull, bear, grey, and zero), he modified the return value a bit: -9 to -1 = Bearish -0.9 to 0.9 = "grey" (and zero) 1 to 9 = Bullish The "grey" range corresponds to the "grey" values plotted by Dale's indicator, but they're divided by 10. So -0.4 is equivalent to "grey -4" in Dale's indicator. * I got rid of a bit of extra computation in the function. I didn't try to do a hard-core Pierre-style optimization :-), but I noticed several significant chunks of calculation were being done several times each bar, and I commented them out and replaced them with an intermediate variable. It still calls sine/cosine a dozen times on each bar, which accounts for the bulk of the processing time, but I think it's a bit easier to understand what the code is doing this way. (It also seems to work better -- see below.) For the most part I didn't try to use mnemonic names for these intermediate variables, because I don't understand exactly what the values represent!! * I'm appending a simplified Confluence indicator using the function. * I've also appended a simple Confluence system. This system sets an entry stop above/below the current bar if Confluence goes into bull/bear mode, and similarly sets an exit stop below/above the bar where it exits bull/bear mode. There's also an optional "aggressive" stop mode that tightens the stops if the market moves in your direction; for example, if the high is 1000 and your "Trigger" offset is 2, the initial stop is set at 1002. If the next bar has a high of 997, the stop is tightened to 997+2=999. Interestingly, when I first wrote this system, I ran into a strange MaxBarsBack problem. The Confluence indicator worked just fine with a MaxBarsBack setting of "Auto-Detect." But systems don't have a setting like that -- you have to specify a fixed value. But NO fixed value (up to the maximum of 999) worked for either the system OR the indicator! And I couldn't see anywhere that it was looking back that many bars. Then, when I did the optimization on the Confluence code, the MaxBarsBack problem mysteriously disappeared. Sometimes TradeStation is just spooky... Any ideas what happened? I've appended a sample system report for the system on SPX, using the default parameters. The system actually does pretty well. It probably won't make anyone rich, but I thought some folks might enjoy playing with it. There are some other things you could do with it -- e.g. it might be interesting to change it to look for long opportunities when Confluence hits -9, and short when it hits 9. If I get a chance to throw that together, I'll post it to the list. Have fun, Gary **********************************/ var fpArray = new Array(); var bInit = false; function preMain() { setStudyTitle("Confluence"); setCursorLabelName("Bull", 0); setCursorLabelName("Bear", 1); setCursorLabelName("ZERO", 2); setCursorLabelName("Grey", 3); setShowCursorLabel(true); setDefaultBarFgColor(Color.blue, 0); setDefaultBarFgColor(Color.red, 1); setDefaultBarFgColor(Color.green, 2); setDefaultBarFgColor(Color.grey, 3); setPlotType(PLOTTYPE_HISTOGRAM, 0); setPlotType(PLOTTYPE_HISTOGRAM, 1); setPlotType(PLOTTYPE_HISTOGRAM, 2); setPlotType(PLOTTYPE_HISTOGRAM, 3); setDefaultBarThickness(2, 0); setDefaultBarThickness(2, 1); setDefaultBarThickness(2, 2); setDefaultBarThickness(2, 3); setStudyMax(11); setStudyMin( - 11); var x = 0; fpArray[x] = new FunctionParameter("Harmonic", FunctionParameter.NUMBER); with(fpArray[x++]) { setLowerLimit(1); setDefault(10); } fpArray[x] = new FunctionParameter("sPrice", FunctionParameter.STRING); with(fpArray[x++]) { setName("Price Data To Use"); addOption("open"); addOption("high"); addOption("low"); addOption("close"); addOption("hl2"); addOption("hlc3"); addOption("ohlc4"); setDefault("close"); } } var STL = 0; var ITL = 0; var LTL = 0; var HOFF = 0; var SOFF = 0; var IOFF = 0; var LTOFF = 0; var ErrNum = 0; var momNum = 0; var TCNum = 0; var xPrice = null; var xHavg = null; var xSavg = null; var xIavg = null; var xLavg = null; var xvalue2 = null; var xvalue3 = null; var xvalue12 = null; var xmomsig = null; var xH2 = null; var xS2 = null; var xI2 = null; var xL2 = null; var xvalue5 = null; var xvalue6 = null; var xvalue7 = null; var xvalue13 = null; var xmom = null; var xSum = null; var xErr = null; var xErrSig = null; var xErrSum = null; var xvalue70 = null; var xvalue71 = null; function main(sPrice, Harmonic) { var nBarState = getBarState(); if (nBarState == BARSTATE_ALLBARS) { if (sPrice == null) sPrice = "close"; if (Harmonic == null) Harmonic = 10; } if (bInit == false) { STL = Math.round((Harmonic * 2) - 1 - 0.5); ITL = Math.round((STL * 2) - 1 - 0.5); LTL = Math.round((ITL * 2) - 1 - 0.5); HOFF = Math.round(Harmonic / 2 - 0.5); SOFF = Math.round(STL / 2 - 0.5); IOFF = Math.round(ITL / 2 - 0.5); xPrice = eval(sPrice)(); xHavg = sma(Harmonic, xPrice); xSavg = sma(STL, xPrice); xIavg = sma(ITL, xPrice); xLavg = sma(LTL, xPrice); xvalue2 = efsInternal("Calc_Values2", SOFF, HOFF, IOFF, xHavg, xSavg, xIavg, xLavg); xvalue3 = getSeries(xvalue2, 1); xvalue12 = getSeries(xvalue2, 2); xmomsig = efsInternal("Calc_MOMSig", xvalue2, xvalue3, xvalue12); xvalue5 = efsInternal("Calc_Values", Harmonic, STL, ITL, LTL, xHavg, xSavg, xIavg, xLavg, sma(Harmonic - 1, xPrice), sma(STL - 1, xPrice), sma(ITL - 1, xPrice), sma(LTL - 1, xPrice)); xvalue6 = getSeries(xvalue5, 1); xvalue7 = getSeries(xvalue5, 2); xvalue13 = getSeries(xvalue5, 3); xmom = efsInternal("Calc_xMOM", HOFF, SOFF, IOFF, xvalue5, xvalue6, xvalue7, xvalue13); xSum = efsInternal("Calc_Sum_Err", xvalue5, xvalue6, xvalue7, xHavg, xSavg, xIavg); xErr = getSeries(xSum, 1); xErrSum = efsInternal("Calc_ErrSum", SOFF, xSum, xErr, xHavg); xErrSig = sma(SOFF, xErrSum); xvalue70 = efsInternal("Calc_Value70", xvalue5, xvalue13); xvalue71 = sma(Harmonic, xvalue70); bInit = true; } if (xvalue71.getValue(0) == null) return; var nErrSum = xErrSum.getValue(0); var nErrSum1 = xErrSum.getValue( - 1); var nErrSig = xErrSig.getValue(0); var nmom = xmom.getValue(0); var nmom1 = xmom.getValue( - 1); var nmomsig = xmomsig.getValue(0); var nvalue70 = xvalue70.getValue(0); var nvalue701 = xvalue70.getValue( - 1); var nvalue71 = xvalue71.getValue(0); if (nErrSum > 0) { if ((nErrSum < nErrSum1) && (nErrSum < nErrSig)) ErrNum = 1; if ((nErrSum < nErrSum1) && (nErrSum > nErrSig)) ErrNum = 2; if ((nErrSum > nErrSum1) && (nErrSum < nErrSig)) ErrNum = 2; if ((nErrSum > nErrSum1) && (nErrSum > nErrSig)) ErrNum = 3; } if (nErrSum < 0) { if ((nErrSum > nErrSum1) && (nErrSum > nErrSig)) ErrNum = -1; if ((nErrSum < nErrSum1) && (nErrSum > nErrSig)) ErrNum = -2; if ((nErrSum > nErrSum1) && (nErrSum < nErrSig)) ErrNum = -2; if ((nErrSum < nErrSum1) && (nErrSum < nErrSig)) ErrNum = -3; } if (nmom > 0) { if ((nmom < nmom1) && (nmom < nmomsig)) momNum = 1; if ((nmom < nmom1) && (nmom > nmomsig)) momNum = 2; if ((nmom > nmom1) && (nmom < nmomsig)) momNum = 2; if ((nmom > nmom1) && (nmom > nmomsig)) momNum = 3; } if (nmom < 0) { if ((nmom > nmom1) && (nmom > nmomsig)) momNum = -1; if ((nmom < nmom1) && (nmom > nmomsig)) momNum = -2; if ((nmom > nmom1) && (nmom < nmomsig)) momNum = -2; if ((nmom < nmom1) && (nmom < nmomsig)) momNum = -3; } if (nvalue70 > 0) { if ((nvalue70 < nvalue701) && (nvalue70 < nvalue71)) TCNum = 1; if ((nvalue70 < nvalue701) && (nvalue70 > nvalue71)) TCNum = 2; if ((nvalue70 > nvalue701) && (nvalue70 < nvalue71)) TCNum = 2; if ((nvalue70 > nvalue701) && (nvalue70 > nvalue71)) TCNum = 3; } if (nvalue70 < 0) { if ((nvalue70 > nvalue701) && (nvalue70 > nvalue71)) TCNum = -1; if ((nvalue70 < nvalue701) && (nvalue70 > nvalue71)) TCNum = -2; if ((nvalue70 > nvalue701) && (nvalue70 < nvalue71)) TCNum = -2; if ((nvalue70 < nvalue701) && (nvalue70 < nvalue71)) TCNum = -3; } var value42 = ErrNum + momNum + TCNum; var Confluence = 0.0; if ((value42 > 0) && (nvalue70 > 0)) Confluence = value42; if ((value42 < 0) && (nvalue70 < 0)) Confluence = value42; if (((value42 > 0) && (nvalue70 < 0)) || ((value42 < 0) && (nvalue70 > 0))) Confluence = value42 / 10; var Res1 = null; var Res2 = null; var Res3 = null; var Res4 = null; if (Confluence >= 1) Res1 = Confluence; if (Confluence <= -1) Res2 = Confluence; if (Confluence == 0) Res3 = 0; else if ((Confluence > -1) && (Confluence < 1)) Res4 = 10 * Confluence; return new Array(Res1, Res2, Res3, Res4); } function Calc_MOMSig(xvalue2, xvalue3, xvalue12) { var nRes = 0; nRes = xvalue2.getValue(0) + xvalue3.getValue(0) + xvalue12.getValue(0); if (nRes == null) { return; } return nRes; } var bSecondInit = false; var xLavgOHLC = null; function Calc_Values(Harmonic, STL, ITL, LTL, xHavg, xSavg, xIavg, xLavg, xH2, xS2, xI2, xL2) { if (bSecondInit == false) { xLavgOHLC = sma(LTL - 1, ohlc4()); bSecondInit = true; } var DerivH = (xHavg.getValue(0) * 2) - xHavg.getValue( - 1); var DerivS = (xSavg.getValue(0) * 2) - xSavg.getValue( - 1); var DerivI = (xIavg.getValue(0) * 2) - xIavg.getValue( - 1); var DerivL = (xLavg.getValue(0) * 2) - xLavg.getValue( - 1); var SumDH = Harmonic * DerivH; var SumDS = STL * DerivS; var SumDI = ITL * DerivI; var SumDL = LTL * DerivL; var LengH = Harmonic - 1; var LengS = STL - 1; var LengI = ITL - 1; var LengL = LTL - 1; var nH2 = xH2.getValue(0); var nS2 = xS2.getValue(0); var nI2 = xI2.getValue(0); var N1H = nH2 * LengH; var N1S = nS2 * LengS; var N1I = nI2 * LengI; var N1L = xL2.getValue(0) * LengL; var DRH = SumDH - N1H; var DRS = SumDS - N1S; var DRI = SumDI - N1I; var DRL = SumDL - N1L; var SumH = nH2 * (Harmonic - 1); var SumS = nS2 * (STL - 1); var SumI = nI2 * (ITL - 1); var SumL = xLavgOHLC.getValue(0) * (LTL - 1); var value5 = (SumH + DRH) / Harmonic; var value6 = (SumS + DRS) / STL; var value7 = (SumI + DRI) / ITL; var value13 = (SumL + DRL) / LTL; if (value5 == null || value6 == null || value7 == null || value13 == null) return; return new Array(value5, value6, value7, value13); } function Calc_xMOM(HOFF, SOFF, IOFF, xvalue5, xvalue6, xvalue7, xvalue13) { var value9 = xvalue6.getValue(0) - xvalue5.getValue( - HOFF); var value10 = xvalue7.getValue(0) - xvalue6.getValue( - SOFF); var value14 = xvalue13.getValue(0) - xvalue7.getValue( - IOFF); var nRes = value9 + value10 + value14; if (nRes == null) return; return nRes; } function Calc_Sum_Err(xvalue5, xvalue6, xvalue7, xHavg, xSavg, xIavg) { var nvalue5 = xvalue5.getValue(0); var nHavg = xHavg.getValue(0); var nvalue6 = xvalue6.getValue(0); var nSavg = xSavg.getValue(0); var nvalue7 = xvalue7.getValue(0); var nIavg = xIavg.getValue(0); var HT = Math.sin(nvalue5 * 2 * Math.PI / 360) + Math.cos(nvalue5 * 2 * Math.PI / 360); var HTA = Math.sin(nHavg * 2 * Math.PI / 360) + Math.cos(nHavg * 2 * Math.PI / 360); var ST = Math.sin(nvalue6 * 2 * Math.PI / 360) + Math.cos(nvalue6 * 2 * Math.PI / 360); var STA = Math.sin(nSavg * 2 * Math.PI / 360) + Math.cos(nSavg * 2 * Math.PI / 360); var IT = Math.sin(nvalue7 * 2 * Math.PI / 360) + Math.cos(nvalue7 * 2 * Math.PI / 360); var ITA = Math.sin(nIavg * 2 * Math.PI / 360) + Math.cos(nIavg * 2 * Math.PI / 360); var Sum = HT + ST + IT; var Err = HTA + STA + ITA; if (Sum == null || Err == null) return; return new Array(Sum, Err); } function Calc_ErrSum(SOFF, xSum, xErr, xHavg) { var nSum = xSum.getValue(0); var nHavg = xHavg.getValue(0); var nSumSOFF = xSum.getValue( - SOFF); var nHavgSOFF = xHavg.getValue( - SOFF); var Condition2 = (((nSum > nSumSOFF) && (nHavg < nHavgSOFF)) || ((nSum < nSumSOFF) && (nHavg > nHavgSOFF))); var Phase = 1; if (Condition2) Phase = -1; var ErrSum = (nSum - xErr.getValue(0)) * Phase; if (ErrSum == null) return; return ErrSum; } function Calc_Value70(xvalue5, xvalue13) { var value70 = xvalue5.getValue(0) - xvalue13.getValue(0); if (value70 == null) return; return value70; } function Calc_Values2(SOFF, HOFF, IOFF, xHavg, xSavg, xIavg, xLavg) { var value2 = xSavg.getValue(0) - xHavg.getValue( - HOFF); var value3 = xIavg.getValue(0) - xSavg.getValue( - SOFF); var value12 = xLavg.getValue(0) - xIavg.getValue( - IOFF); if (value2 == null || value3 == null || value12 == null) return; return new Array(value2, value3, value12) }