Download software Tutorial videos
Subscription & data-feed pricing Class schedule


New account application Trading resources
Margin rates Stock & option commissions

Attention: Discussion forums are read-only for extended maintenance until further notice.
Welcome Guest, please sign in to participate in a discussion. Search | Active Topics |

Zig-zag pcf based off other platform logic Rate this Topic:
Previous Topic · Next Topic Watch this topic · Print this topic ·
esc
Posted : Saturday, March 11, 2017 6:44:38 AM
Gold Customer Gold Customer

Joined: 3/11/2013
Posts: 24

I was asked for help converting an indicator used in another platform into a scan pcf for TC2000.  This one is beyond me.  I realize that previous forum posts indicate 1) TC2000 does not currently have a zig-zag indicator and 2) a possibly related indicator from even a different platform was referred to development a few years back.

However, I did not know if anyone had tried to convert this particular 3rd-party code...and whether it might be more doable than the MT version referenced in 2015 and before.  At the very least, I figured it was worth a shot since another TC user had asked me.  So, below are the code for Zig-zag indicator and the function that it calls.

Any shot that it can be converted to pcf?

------------------------

Main script:

input priceH = high;
input priceL = low;
input percentageReversal = 5.0;
input absoluteReversal = 0.0;
input atrLength = 5;
input atrReversal = 1.5;
 
def zigZag = reference ZigZagHighLow(priceH, priceL, percentageReversal, absoluteReversal, atrLength, atrReversal).ZZ;
 
def step1 = open[1] >= open and open >= close[1] and open[1] > close[1];
def step2 = open[1] <= open and open <= close[1] and open[1] < close[1];
 
def upStep1 = step1 and close > open[1];
def upStep2 = step2 and close > close[1];
def downStep1 = step1 and close < close[1];
def downStep2 = step2 and close < open[1];
 
plot UpStep = (upStep1 or upStep1[-1] or upStep2 or upStep2[-1]) and zigZag == low;
plot DownStep = (downStep1 or downStep1[-1] or downStep2 or downStep2[-1]) and zigZag == high;
 

In my mind, this would be 2 pcfs...one for "Upstep Zig-Zag" and one for "DownStep Zig-Zag."  I have taken the step of converting this easier portion to pcf as follows:

UpStep:

(O1 >= O and
 O >= C1 and
 O1 > C1 and
 C > O1)
OR
(O1 <= O and
 O <= C1 and
 O1 < C1 and
 C > C1)
OR
(O2 >= O1 and
 O1 >= C2 and
 O2 > C2 and
 C1 > O2)
OR
(O2 <= O1 and
 O1 <= C2 and
 O2 < C2 and
 C1 > C2)
 
-----------------


DownStep:

(O1 >= O and
 O >= C1 and
 O1 > C1 and
 C < C1)
OR
(O2 >= O1 and
 O1 >= C2 and
 O2 > C2 and
 C1 < C2)
OR
(O1 <= O and
 O <= C1 and
 O1 < C1 and
 C < O1)
OR
(O2 <= O1 and
 O1 <= C2 and
 O2 < C2 and
 C1 < O2)

 

----------------------------------------------------------------------------------------

This is where things get ugly.  The function called above "ZigZagHighLow" contains this code, which is beyond my time and/or ability to convert.

 

ZigZagHighLow function:
 
 
input priceH = high;
input priceL = low;
input percentageReversal = 5.0;
input absoluteReversal = 0.0;
input atrLength = 5;
input atrReversal = 1.5;
 
Assert(percentageReversal >= 0, "'percentage reversal' must not be negative: " + percentageReversal);
Assert(absoluteReversal >= 0, "'absolute reversal' must not be negative: " + absoluteReversal);
Assert(atrReversal >= 0, "'atr reversal' must not be negative: " + atrReversal);
Assert(percentageReversal != 0 or absoluteReversal != 0 or atrReversal != 0, "Either 'percentage reversal' or 'absolute reversal' or 'atr reversal' must not be zero");
 
def hlPivot;
if (atrReversal != 0) {
    hlPivot = percentageReversal / 100 + WildersAverage(TrueRange(high, close, low), atrLength) / close * atrReversal;
} else {
    hlPivot = percentageReversal / 100;
}
def state = {default init, undefined, uptrend, downtrend};
def maxPriceH;
def minPriceL;
def newMax;
def newMin;
def prevMaxH = GetValue(maxPriceH, 1);
def prevMinL = GetValue(minPriceL, 1);
 
if GetValue(state, 1) == GetValue(state.init, 0) {
    maxPriceH = priceH;
    minPriceL = priceL;
    newMax = yes;
    newMin = yes;
    state = state.undefined;
} else if GetValue(state, 1) == GetValue(state.undefined, 0) {
    if priceH >= prevMaxH {
        state = state.uptrend;
        maxPriceH = priceH;
        minPriceL = prevMinL;
        newMax = yes;
        newMin = no;
    } else if priceL <= prevMinL {
        state = state.downtrend;
        maxPriceH = prevMaxH;
        minPriceL = priceL;
        newMax = no;
        newMin = yes;
    } else {
        state = state.undefined;
        maxPriceH = prevMaxH;
        minPriceL = prevMinL;
        newMax = no;
        newMin = no;
    }
} else if GetValue(state, 1) == GetValue(state.uptrend, 0) {
    if priceL <= prevMaxH - prevMaxH * hlPivot - absoluteReversal {
        state = state.downtrend;
        maxPriceH = prevMaxH;
        minPriceL = priceL;
        newMax = no;
        newMin = yes;
    } else {
        state = state.uptrend;
        if (priceH >= prevMaxH) {
            maxPriceH = priceH;
            newMax = yes;
        } else {
            maxPriceH = prevMaxH;
            newMax = no;
        }
        minPriceL = prevMinL;
        newMin = no;
    }
} else {
    if priceH >= prevMinL + prevMinL * hlPivot + absoluteReversal {
        state = state.uptrend;
        maxPriceH = priceH;
        minPriceL = prevMinL;
        newMax = yes;
        newMin = no;
    } else {
        state = state.downtrend;
        maxPriceH = prevMaxH;
        newMax = no;
        if (priceL <= prevMinL) {
            minPriceL = priceL;
            newMin = yes;
        } else {
            minPriceL = prevMinL;
            newMin = no;
        }
    }
}
 
def barNumber = BarNumber();
def barCount = HighestAll(If(IsNaN(priceH), 0, barNumber));
def newState = GetValue(state, 0) != GetValue(state, 1);
def offset = barCount - barNumber + 1;
def highPoint = state == state.uptrend and priceH == maxPriceH;
def lowPoint = state == state.downtrend and priceL == minPriceL;
 
def lastH;
if highPoint and offset > 1 {
    lastH = fold iH = 1 to offset with tH = priceH while !IsNaN(tH) and !GetValue(newState, -iH) do if GetValue(newMax, -iH) or iH == offset - 1 and GetValue(priceH, -iH) == tH then Double.NaN else tH;
} else {
    lastH = Double.NaN;
}
 
def lastL;
if lowPoint and offset > 1 {
    lastL = fold iL = 1 to offset with tL = priceL while !IsNaN(tL) and !GetValue(newState, -iL) do if GetValue(newMin, -iL) or iL == offset - 1 and GetValue(priceL, -iL) == tL then Double.NaN else tL;
} else {
    lastL = Double.NaN;
}
 
plot ZZ;
if barNumber == 1 {
    ZZ = fold iF = 1 to offset with tP = Double.NaN while IsNaN(tP) do if GetValue(state, -iF) == GetValue(state.uptrend, 0) then priceL else if GetValue(state, -iF) == GetValue(state.downtrend, 0) then priceH else Double.NaN;
} else if barNumber == barCount {
    ZZ = if highPoint or state == state.downtrend and priceL > minPriceL then priceH else if lowPoint or state == state.uptrend and priceH < maxPriceH then priceL else Double.NaN;
} else {
    ZZ = if !IsNaN(lastH) then lastH else if !IsNaN(lastL) then lastL else Double.NaN;
}
ZZ.SetDefaultColor(GetColor(1));
ZZ.EnableApproximation();

 

Many thanks in advance for my friend.  I wish I could give you more background on the usage of this for trading, but it is not my setup.  However, I will ask the original requester to fill in some detail in this thread.

Thanks Bruce and/or any other person that can help!

Bruce_L
Posted : Monday, March 13, 2017 9:59:06 AM


Worden Trainer

Joined: 10/7/2004
Posts: 65,138

No, there really isn't any good way to do this in TC2000.



-Bruce
Personal Criteria Formulas
TC2000 Support Articles
Users browsing this topic
Guest-1

Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.