Confluence

ICE Data Services -

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)
}